初次学习Spring 的AOP,就写了一个日志切面,对控制层的接受和返回请求进行切面。
@Aspect
@ComponentpublicclassLogAspect{//在controller设计一个切面,来记录请求数据和返回数据private final Logger logger= LoggerFactory.getLogger(this.toString());
@Pointcut("execution(* com.zph.springbootapi.api.*.*(..))")publicvoidlog(){}
@Before("log()")publicvoiddoBefore(){
logger.info("--------doBefore 1----------");}
@After("log()")publicvoiddoAfter(){
logger.info("--------doAfter 2----------");}
@AfterReturning(returning="result",pointcut="log()")publicvoiddoAfterReturning(Object result){
logger.info("--------doAfterReturning ----------:内容{}",result);}
@AfterThrowing(pointcut="log()", throwing="ex")publicvoiddoAfterThrowing(Exception ex){
logger.info("--------doAfterThrowing ---------- :{}",ex.getMessage());}
@Around("log()")publicvoiddoAround(){
logger.info("--------doAround ---------- ");}}
因为这五个处理方式都用上了,所以结果如下图所示:
然后就好奇为什么,@Before没有被调用,经过资料的查阅发现,AOP首先进入@Around
图片来源:https://blog.csdn.net/qq_41981107/article/details/85260765
@Around作用
1.可以在目标方法之前进行增强动作,也可以执行完目标方法后执行
2.可以决定目标方法何时,以何种方式执行,甚至可以不执行
3.可以改变目标方法的参数值,也可以改变执行目标方法之后的返回值;当需要改变目标方法的返回值时只能使用@Around
注意: 使用@Around的方法的第一个形参必须是ProceedJoinPoint类型,只有待哦用该参数的proceed()方法才会调用目标函数。
ProceedJoinPoint是JoinPoint的子类,多了proceed()方法,并可以抛出异常。
一般的写法如下:
@Around("log()")public ObjectdoAround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable{
logger.info("--------doAround ---------- ");//执行目标方法
Object obj=proceedingJoinPoint.proceed();//只有返回了obj,@AfterReturning才获取返回的结果,否则哪里的result为nullreturn obj;}
显示结果如下:
参考文献
https://my.oschina.net/itblog/blog/211693
https://blog.csdn.net/qq_41981107/article/details/85260765