Puntos de conocimiento de SpringAOP Daquan presenta la expresión pointcut en detalle

Inducción de puntos de conocimiento

1. Introducción y uso de expresiones de punto de entrada de AOP

2. Ejemplos para introducir el orden de ejecución de las notificaciones

3. Ejecución de notificaciones por rondas

4. Spring aop basado en la configuración xml

4. ¿Qué se basa mejor en anotaciones y xml?

Expresión de punto de entrada AOP

Spring aop admite la realización de identificadores de corte de AspectJ, que se utilizan para expresiones de corte. Los más utilizados son 1, 2, 4.

1. La ejecución se utiliza para hacer coincidir los puntos de conexión del método, el identificador de corte de puntos más utilizado, se puede hacer coincidir con el nivel del método, de forma detallada. Basado en el método.

    @Before (“ejecución (* cn.allen.service.impl. *. * (..))”)

2. @annotation coincide con los métodos que tienen esta anotación. Basado en anotaciones.

    @Before (“@ anotación (jdk.nashorn.internal.runtime.logging.Logger)”)

3. @within solo puede coincidir con el nivel de la clase, y hay una cierta anotación en la clase complementaria.

4. Se utiliza para hacer coincidir la clase que implementa una interfaz. Basado en la interfaz.

5. Los argumentos se corresponden con parámetros.

La expresión fusiona && ||!, Correspondiente a AND o NOT

@Before (“ejecución (* cn.allen.service.impl. *. * (..)) && @annotation (jdk.nashorn.internal.runtime.logging.Logger)")

Orden de ejecución de las notificaciones de Spring AOP

Secuencia de ejecución: pre-posición -> post-posición -> post-anormal -> post-retorno

正常 : @Before -> Método -> @After -> @AfterReturning

异常 : @Before -> Método -> @After -> @AfterThrowing

Ejemplos de descripciones de notificación previa, notificación posterior, notificación posterior a la devolución y notificación posterior a anomalías.

Agregue un punto de conocimiento, JoinPoint es el punto de enlace que mencionamos anteriormente, en el que puede obtener información específica dentro del método, como el nombre del método, los parámetros del método, los ejemplos específicos son los siguientes

La notificación previa @Before se ejecutará antes que el método llamado.

Publicar notificación @Después, ejecutado después del método llamado

La notificación posterior a la devolución @AfterReturning se ejecuta antes de que el método llamado esté a punto de completarse y se devuelva la estructura.

El pase posterior a la excepción @AfterThrowing, que se ejecutará cuando el método llamado envíe una excepción real.

@Component
@Aspect
public class LogAspect {
    @Before("execution(* com.allen.trainning.spring.aop.dao.impl.*.*(..))")
    public void before(JoinPoint point){
        System.out.println("@Before --- "+ point.getArgs()[0] + " is the name for a candidate girl!");
    }

    @After("execution(* com.allen.trainning.spring.aop.dao.impl.*.*(..))")
    public void after(JoinPoint point){
        System.out.println("@Before --- "+ point.getSignature().getName() + " was been called just now!");
    }

    @AfterReturning(value = "execution(* com.allen.trainning.spring.aop.dao.impl.*.*(..))", returning = "returnVal")
    public void afterReturn( Object returnVal){
        XiaoJieJie xiaojiejie = (XiaoJieJie)returnVal;
        System.out.println("@AfterReturning --- "+ xiaojiejie.getName() + " have been returned !");
    }

    @AfterThrowing(value = "execution(* com.allen.trainning.spring.aop.dao.impl.*.*(..))", throwing = "errorInfo")
    public void afterException(Exception errorInfo){
        StringWriter sw = new StringWriter();
        errorInfo.printStackTrace(new PrintWriter(sw,true));
        System.out.println("@AfterThrowing --- unexpected result happens, please check !!!" + sw.getBuffer().toString() );
    }
}

Hay 2 métodos de corte, getByage y getByName:

@Repository
public  class GetXiaoJieJieDaoImpl implements GetXiaoJieJieDao {
    public  XiaoJieJie getByAge(Integer age){
        System.out.println("--- method getByAge is been calling ---!");
        if (age==null){
            throw new RuntimeException("age is null ,please check");
        }
        return new XiaoJieJie("Lucy",age);
    }
    public  XiaoJieJie getByName(String name){
        System.out.println("--- method getByName is been calling ---!");
        return new XiaoJieJie(name,18);
    }
}

prueba:

public class TestAop {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext xml = new ClassPathXmlApplicationContext("spring.xml");
        GetXiaoJieJieDao findXiaojiejie = xml.getBean(GetXiaoJieJieDao.class);
        XiaoJieJie girl = findXiaojiejie.getByName("lulu");
        girl.play();
        findXiaojiejie.getByAge(null);
    }
}

Resultados de:

@Before --- lulu is the name for a candidate girl!
--- method getByName is been calling ---!
@Before --- getByName was been called just now!
@AfterReturning --- lulu have been returned !
my Master, I am lulu ,18 years old, will you play with me
@Before --- null is the name for a candidate girl!
--- method getByAge is been calling ---!
@Before --- getByAge was been called just now!
@AfterThrowing --- unexpected result happens, please check !!!java.lang.RuntimeException: age is null ,please check
	at com.allen.trainning.spring.aop.dao.impl.GetXiaoJieJieDaoImpl.getByAge(GetXiaoJieJieDaoImpl.java:13)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.lang.reflect.Method.invoke(Method.java:498)
	at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:343)

Cada uno de los métodos de notificación anteriores ha escrito su propia expresión de corte de puntos, y todos son iguales, lo que parece muy poco elegante. Variables de pointcut, este concepto puede ayudarnos a resolver este problema. En este momento, usamos la anotación de pointcut @PointCut, de la siguiente manera

    @Pointcut("execution(* com.allen.trainning.spring.aop.dao.impl.*.*(..))")
    public void pointCut(){
    }

 Por lo tanto, las expresiones pointcut en las notificaciones anteriores se pueden reemplazar con pointCut ().

    @Before("pointCut()")
    @After("pointCut()")
    @AfterReturning(value = "pointCut()", returning = "returnVal")
    @AfterThrowing(value = "pointCut()", throwing = "errorInfo")

Uso de la notificación envolvente @Around

La notificación circundante es simplemente una notificación para reemplazar las cuatro notificaciones anteriores, la implementación específica es la siguiente:

@Component
@Aspect
public class LogAspectPointCut {
    @Around("pointCut()")
    public Object around(ProceedingJoinPoint joinpoint) {
        String methodName = joinpoint.getSignature().getName(); //获取方法名字
        String paraValue = (String)joinpoint.getArgs()[0];//获取方法参数
        Object object = null;
        try {
            System.out.println("前置通知" + methodName+ paraValue);
            object = joinpoint.proceed();
            System.out.println("前置通知");
        } catch (Throwable throwable) {
            System.out.println("异常通知");
        } finally {
            System.out.println("返回通知");
        }
        return object;
    }
}

Resultados de:

前置通知 方法名:getByName 参数:lulu
--- method getByName is been calling ---!
后置通知
返回通知
my Master, I am lulu ,18 years old, will you play with me
前置通知 方法名:getByAge 参数:null
--- method getByAge is been calling ---!
异常通知
返回通知

Process finished with exit code 0

Configurar AOP basado en XML

No puede usar && en xml, necesita escapar & amp; & amp;

La configuración específica es la siguiente:

El primer paso es eliminar la configuración de la anotación enable aop

<aop: aspectj-autoproxy />

El segundo paso es configurar el aopconfig

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

<context:component-scan base-package="com.allen.trainning.spring.aop"/>
    <aop:config>
        <aop:aspect ref="logAspect">
            <aop:pointcut id="logPointcut" expression="execution(* com.allen.trainning.spring.aop.dao.impl.*.*(..))"></aop:pointcut>
            <aop:before method="before" pointcut="execution(* com.allen.trainning.spring.aop.dao.impl.*.*(..))&amp;&amp;execution(* com.allen.trainning.spring.aop.dao.impl.*.*(Integer))"></aop:before>
            <aop:after method="after" pointcut-ref="logPointcut"></aop:after>
            <aop:after-returning method="afterReturn" pointcut-ref="logPointcut" returning="returnVal"></aop:after-returning>
            <aop:after-throwing method="afterException" throwing="errorInfo" pointcut-ref="logPointcut"></aop:after-throwing>
        </aop:aspect>
    </aop:config>

    <aop:config>
        <aop:aspect ref="logAspectPointCut">
            <aop:pointcut id="logPointcut" expression="execution(* com.allen.trainning.spring.aop.dao.impl.*.*(..))"></aop:pointcut>
            <aop:around method="around" pointcut-ref="logPointcut" ></aop:around>
        </aop:aspect>
    </aop:config>
</beans>

El resultado de la prueba, que es el mismo que el resultado de la prueba comentado, no se publicará dos veces.

¿Qué pasa con las anotaciones y xml, eran anotaciones en ese momento

De la siguiente manera, las anotaciones pueden combinar varias expresiones de corte de puntos definidas por sí mismas, xml no funciona

Las anotaciones también son relativamente simples y cómodas de usar.

Preguntas de entrevista:

1. ¿Cuáles son los tipos de notificación de primavera aop?

2. ¿Cuáles son los pasos de la implementación de anotaciones e xml?

 

Supongo que te gusta

Origin blog.csdn.net/pengweismile/article/details/109849548
Recomendado
Clasificación