Aprendamos el uso de la serie SF framework 7.2-spring-AOP-AOP

Spring AOP tiene dos modos de uso: modo de configuración @AspectJ y modo de configuración xml.

Modo de configuración @AspectJ

Configuración

1. Agregue paquetes de dependencia:

    <!--spring aop依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>6.0.2</version>
    </dependency>
    <!-- spring aspects依赖-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aspects</artifactId>
        <version>6.0.2</version>
    </dependency>

2. Agregue el archivo de configuración:

<beans xmlns="http://www.springframework.org/schema/beans"
	...
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="
		...
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop.xsd">

	<!-- 开启aop注解方式,默认为false -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

Ejemplo

Definición de aspecto

@Component
// @Aspect切面注解,表示该类是切面类
@Aspect
public class AspectLog {
    
     
	// before advice,括号中是切入点配置,省略了“pointcut”(execution是pointcut语法的固定开头) 注1
    @Before("execution(* com.learnsf.demo.spring.aop.BzServiceImpl.*(..))")
	public void before() {
    
    
		System.out.println("方法执行advice-before");
	}

	// After advice,括号中是切入点配置,省略了“pointcut”
    @After("execution(* com.learnsf.demo.spring.aop.BzServiceImpl.*(..))")
	public void after() {
    
    
		System.out.println("方法执行advice-after");
	}

	// AfterReturning advice,括号中是切入点配置,省略了“pointcut”
    @AfterReturning("execution(* com.learnsf.demo.spring.aop.BzServiceImpl.*(..))")
	public void afterReturning() {
    
    
		System.out.println("方法执行advice-afterReturning");
	}

	// Around advice,括号中是切入点配置,省略了“pointcut” 注2
    /**在使用环绕注解时,可以传入ProceedingJoinPoint的对象来获取业务方法的返回值*/
    @Around("execution(* com.learnsf.demo.spring.aop.BzServiceImpl.around*(..))")
    public void around(ProceedingJoinPoint pj) throws Throwable {
    
    
        // 执行方法前处理
        System.out.println("方法执行advice-@Around前");
        // 执行方法本身
        BzService bzService =(BzService) pj.proceed();
        // 执行方法后处理
        System.out.println("方法执行advice-@Around后,返回值-"+bzService);
    }

	// AfterThrowing advice,其中pointcut是切入点,throwing是传入切面异常命名为"ex" 注3
    @AfterThrowing(pointcut="execution(* com.learnsf.demo.spring.aop.BzServiceImpl.throw*(..))",throwing="ex")
	public void afterThrowing(JoinPoint jp, Throwable ex) {
    
    
		System.out.println("method " + jp.getTarget().getClass().getName() + "." + jp.getSignature().getName() + " throw exception: "+ex.getMessage());
	}
}

Nota 1: Consulte los capítulos siguientes para saber cómo definir los puntos de entrada.
Nota 2: ProceedingJoinPoint hereda de JoinPoint. Donde "pj.proceed()" es el método del punto de conexión de ejecución en sí. Esta es la característica del consejo circundante: el programa de aspecto necesita ejecutar el método del punto de conexión por sí mismo; el marco ejecuta otros consejos.
Nota 3: La interfaz JoinPoint proporciona información sobre los aspectos que pueden acceder a los métodos de punto de unión. Los métodos útiles son los siguientes:
getArgs(): devuelve los parámetros del método.
getThis(): Devuelve el objeto proxy.
getTarget(): Devuelve el objeto de destino.
getSignature(): Devuelve la descripción del método del Consejo actual.
toString(): imprime la descripción del método de asesoramiento actual.

Clase de ejemplo

public interface BzService {
    
    
    public void add();

    public void delete();

    public void update();

    public void query();
    
    public BzService aroundTest();
    
	public BzServiceImpl throwTest() throws Exception;
}

@Component
public class BzServiceImpl implements BzService{
    
    
	@Override
    public void add() {
    
    
        System.out.println("业务增加!");
    }

	@Override
    public void delete() {
    
    
        System.out.println("业务删除!");
    }

	@Override
    public void update() {
    
    
        System.out.println("业务修改!");
    }

	@Override
    public void query() {
    
    
        System.out.println("业务查询!");
    }

	@Override
	public BzServiceImpl aroundTest() {
    
    
        System.out.println("该方法被@Around Annotation!");
        return null;
    }
	@Override
	public BzServiceImpl throwTest() throws Exception{
    
    
        System.out.println("该方法被throw!");
		throw new IllegalArgumentException("测试异常抛出");
	}
}

clase de ejecución

@Component
public class DemoAop {
    
    
	@Autowired
	BzService bzService;
	
	public void demo() {
    
    
		bzService.add();
		bzService.delete();
		bzService.update();
		bzService.aroundTest();
		try {
    
    
			bzService.throwTest();
		} catch (Exception e) {
    
    
			// TODO Auto-generated catch block
			//e.printStackTrace();
		}
	}
}

// 主程序
public class Main {
    
    
    public static void main(String[] args) {
    
    
        //创建springframework容器,初始化文件为app.xml
    	ApplicationContext context = new ClassPathXmlApplicationContext("app.xml");
        DemoAop demoAop = (RunDemo)context.getBean("DemoAop");
        demoAop .demo();
    }
}

Esquema de configuración XML

Configuración

Archivo de configuración agregado:

<beans xmlns="http://www.springframework.org/schema/beans"
	...
	xmlns:aop="http://www.springframework.org/schema/aop"
	xsi:schemaLocation="
		...
		http://www.springframework.org/schema/aop
		http://www.springframework.org/schema/aop/spring-aop.xsd">

	...
	<!--AOP实现方式之一:xml配置模式-->
    <aop:config>
        <!-- 定义切入点:id切入点的id,expression:确定要切入的地方和其详细信息  -->
        <aop:pointcut id="pointcut" expression="execution(* com.learnsf.demo.spring.aop.BzServiceImplForXml.*(..))"/>
        <!-- 同切面关联:advice-ref定义切面 使用的切点pointcut-ref -->
        <aop:advisor advice-ref="springAopLog" pointcut-ref="pointcut"/>
    </aop:config>
    ...

Ejemplo

Tipo de sección

// 通过继承实现对方法的参数、返回值等的访问
@Component
public class SpringAopLog implements MethodBeforeAdvice,AfterReturningAdvice {
    
    
	// implement MethodBeforeAdvice(BeforeAdvice只是个标记接口,MethodBeforeAdvice为实际接口)
	@Override
	public void before(Method method, Object[] args, @Nullable Object target) {
    
    
		System.out.println("[前置Advice]: "+target.getClass().getName()+"的"+method.getName()+"方法被执行了");
	}

	//implement AfterReturningAdvice(AfterAdvice只是个标记接口,AfterReturningAdvice为实际接口)
	// returnValue:切入目标方法的返回值,切入的后置方法可以对返回值进行操作
    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
    
    
        System.out.println("[后置Advice]: 执行了"+method.getName()+"方法,返回值为"+returnValue);
    }
}

Clase de ejemplo

@Component
public class BzServiceImplForXml {
    
    
    public BzPojo add(BzPojo bzPojo) {
    
    
        System.out.println("BzServiceImplForXml-业务增加!");
        return bzPojo;
    }

    public BzPojo update(BzPojo bzPojo) {
    
    
        System.out.println("BzServiceImplForXml-业务修改!");
        return bzPojo;
    }

    public boolean delete(Integer id) {
    
    
        System.out.println("BzServiceImplForXml-业务删除!");
        return true;
    }

    public void query(Integer id) {
    
    
        System.out.println("BzServiceImplForXml-业务查询!");
    }
}

correr

@Component
public class DemoAop {
    
    
	@Autowired
	BzServiceImplForXml bzServiceImplForXml;
	
	public void demo() {
    
    
		BzPojo bzPojo=new BzPojo();
		bzServiceImplForXml.add(bzPojo);
		bzServiceImplForXml.update(bzPojo);
		bzServiceImplForXml.delete(1);
	}
}
// 主程序
public class Main {
    
    
    public static void main(String[] args) {
    
    
        //创建springframework容器,初始化文件为app.xml
    	ApplicationContext context = new ClassPathXmlApplicationContext("app.xml");
        DemoAop demoAop = (RunDemo)context.getBean("DemoAop");
        demoAop .demo();
    }
}

Cómo elegir una aplicación

Para elegir el modo de configuración @AspectJ o el modo de configuración XML para una aplicación, debe comprender la diferencia entre los dos:
1. Utilice Spring AOP para admitir el modo de configuración @AspectJ o el modo de configuración XML al mismo tiempo. Si solo usa AspectJ completo, solo puede usar el modo @AspectJ.
2. El modo de configuración XML es el modo que Spring ha estado utilizando desde su nacimiento, y también es el modo con el que muchos programadores están más familiarizados. Por lo tanto, cuando se utiliza AOP como herramienta para configurar servicios empresariales, XML puede ser una buena opción. Las ventajas del modo de configuración xml son: 1. Se puede ver más claramente qué aspectos existen en el sistema desde la configuración, 2. La configuración se puede cambiar independientemente del programa. También hay dos deficiencias: primero, no encapsula completamente la implementación de los requisitos que resuelve en una sola ubicación, violando el principio DRY (es decir, cualquier responsabilidad en el sistema debe tener una representación única y clara); segundo, es diferente de @ En comparación con el modo de configuración AspectJ, el modo de configuración XML está ligeramente limitado en lo que puede expresar: solo se admiten modelos de creación de instancias de aspecto "singleton" y no es posible combinar puntos de corte con nombre declarados en XML.
De hecho, ambos pueden mezclarse.

Sintaxis de expresión de punto de corte

Sintaxis de Pointcut (citado de: https://blog.51cto.com/panyujie/5604327).
Insertar descripción de la imagen aquí

Supongo que te gusta

Origin blog.csdn.net/davidwkx/article/details/131736546
Recomendado
Clasificación