废话不多说,直接上教程。
aopalliance
aopalliance
1.0
aspectj
aspectjweaver
1.5.4
切点表达式不会写的参考这篇文章: https://blog.csdn.net/yangshangwei/article/details/77627825
这里我编写一个 ControllerAspect 类,来对我的一个 controller 包下的所有的类的方法进行通知。
包含:
直接上代码,代码里面的 @Pointcut 定义切点我在 spring in action 上看的是可行的,但是我代码里面报错,有大神知道为什么欢迎指点。
刚才测试了下,发现 环绕通知和其他的 前置后置一起用可能会有问题。这个注意下。
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import java.util.Arrays;
@Aspect
public class ControllerAspect {
// @Pointcut(" ")
// public void controllerAspect(){}
/**
* 前置通知
* @param jp
*/
@Before(" execution(* com.zzq.controller.*.*(..)) ")
public void before(JoinPoint jp){
String methodName = jp.getSignature().getName();
System.out.println("【前置通知】the method 【" + methodName + "】 execution with " + Arrays.asList(jp.getArgs()));
}
/**
* 后置通知
* @param jp
*/
@After(" execution(* com.zzq.controller.*.*(..)) ")
public void after(JoinPoint jp ){
System.out.println("【后置通知】the method【"+ jp.getSignature().getName() +"】 execution done");
}
/**
* 环绕通知,ProceedingJoinPoint 参数必须要,并且要放行,不然方法就处于阻塞状态
* @param pjp
*/
// @Around(" execution(* com.zzq.controller.*.*(..)) ")
// public void around(ProceedingJoinPoint pjp){
// try{
// String methodName = pjp.getSignature().getName();
// System.out.println("【环绕通知的前置通知】the method execution with...");
// // 放行,不放行方法调用会处于阻塞状态
// pjp.proceed();
// System.out.println("【环绕通知的后置通知】the method execution done " );
// }catch (Throwable e){
// System.out.println("【环绕通知的异常通知】exception:" + e.getMessage() );
// }
// }
/**
* 方法执行完了之后执行,跟上返回值
* @param jp
* @param result
*/
@AfterReturning(pointcut = " execution(* com.zzq.controller.*.*(..)) " , returning = "result")
public void afterReturning(JoinPoint jp, Object result){
String methodName = jp.getSignature().getName();
System.out.println("【返回通知】the method 【" + methodName + "】 ends with 【" + result + "】");
}
/**
* 异常通知,方法出现异常的时候执行
* @param jp
* @param e
*/
@AfterThrowing(value = " execution(* com.zzq.controller.*.*(..)) " , throwing = "e")
public void afterReturning(JoinPoint jp , Throwable e){
String methodName = jp.getSignature().getName();
System.out.println("【异常通知】the method 【" + methodName + "】 has exception 【" + e.getMessage() + "】");
}
}
上面的类写完之后,还不会生效,因为没注入。
此处注入需要 @EnableAspectJAutoProxy 注解
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
@EnableAspectJAutoProxy
@Configuration
public class AspectConfig {
@Bean
public ControllerAspect controllerAspect(){
return new ControllerAspect();
}
}
正常执行:
执行失败:
通知自己的实践发现了 几个问题,不知道结论是否正确,如有不正确还望各位大佬提出。
1.在 切面方法 里面 执行 其他的被代理的方法的时候 aop 是不生效的。
比如说我控制器里面有两个方法,在一个控制器里面调用另外一个控制器的方法,通知是不生效的。
如图:
2.异常通知,如果异常不是发生在该类,是发生在被调用方法里面,并且没有抛出异常,而是直接内部处理,这个 异常通知 是不会统治的。其实方法都没有抛异常,不通知应该也很正常。