一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第23天,点击查看活动详情。
xml配置AOP
①定义切面类
public class MyAspect {
public void before(JoinPoint joinPoint){
System.out.println("before");
}
// @AfterReturning(value = "pt()",returning = "ret")
public void afterReturning(JoinPoint joinPoint,Object ret){
System.out.println("afterReturning:"+ret);
}
// @After("pt()")
public void after(JoinPoint joinPoint){
System.out.println("after");
}
// @AfterThrowing(value = "pt()",throwing = "e")
public void afterThrowing(JoinPoint joinPoint,Throwable e){
String message = e.getMessage();
System.out.println("afterThrowing:"+message);
}
public Object around(ProceedingJoinPoint pjp){
//获取参数
Object[] args = pjp.getArgs();
MethodSignature signature = (MethodSignature) pjp.getSignature();
Object target = pjp.getTarget();
Object ret = null;
try {
ret = pjp.proceed();//目标方法的执行
//ret就是被增强方法的返回值
System.out.println(ret);
} catch (Throwable throwable) {
throwable.printStackTrace();
System.out.println(throwable.getMessage());
}
// System.out.println(pjp);
return ret;
}
}
②目标类和切面类注入容器
在切面类和目标类上加是对应的注解。注入如果是使用注解的方式注入容器要记得开启组件扫描。
当然你也可以在xml中使用bean标签的方式注入容器。
@Component//把切面类注入容器
public class MyAspect {
//..。省略无关代码
}
@Service//把目标类注入容器
public class UserService {
//..。省略无关代码
}
③配置AOP
<?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: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 https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd">
<!--开启组件扫描-->
<context:component-scan base-package="com.sangeng"></context:component-scan>
<!--配置AOP-->
<aop:config>
<!--定义切点-->
<aop:pointcut id="pt1" expression="execution(* com.sangeng.service..*.*(..))"></aop:pointcut>
<aop:pointcut id="pt2" expression="@annotation(com.sangeng.aspect.InvokeLog)"></aop:pointcut>
<!--配置切面-->
<aop:aspect ref="myAspect">
<aop:before method="before" pointcut-ref="pt1"></aop:before>
<aop:after method="after" pointcut-ref="pt1"></aop:after>
<aop:after-returning method="afterReturning" pointcut-ref="pt1" returning="ret"></aop:after-returning>
<aop:after-throwing method="afterThrowing" pointcut-ref="pt2" throwing="e"></aop:after-throwing>
</aop:aspect>
</aop:config>
</beans>
1.9 多切面顺序问题
在实际项目中我们可能会存在配置了多个切面的情况。这种情况下我们很可能需要控制切面的顺序。
我们在默认情况下Spring有它自己的排序规则。(按照类名排序)
默认排序规则往往不符合我们的要求,我们需要进行特殊控制。
如果是注解方式配置的AOP可以在切面类上加 @Order注解 来控制顺序。@Order中的属性越小优先级越高。
如果是XML方式配置的AOP,可以通过调整配置顺序来控制。
例如:
下面这种配置方式就会先使用CryptAspect里面的增强,在使用APrintLogAspect里的增强
@Component
@Aspect
@Order(2)
public class APrintLogAspect {
//省略无关代码
}
@Component
@Aspect
@Order(1)
public class CryptAspect {
//省略无关代码
}