常規使用Spring的AOP功能,都是對一個Service中的B方法進行切入記錄日志,這些時候AOP是能起作用的。但是假如B方法被service中的A方法調用,在B方法上的切入便會失效,導致無法記錄日志。
要弄清楚切入失敗的原因,就要先了解切入的原理。為什么能夠切入目標對象,原理就是創建了代理類,在代理類中在調用目標方法的前后進行切入。比如說目標對象是service,代理對象是$proxy0,這時候切入對B方法的調用就是$proxy0.B(),執行流程就是先記錄日志再調用目標對象service的B方法,所以可以切入;但是A方法$proxy0.A(),只能對A方法增強,A里面調B的時候使用的是service目標對象s.B(),而不是$proxy0.B(),所以對B的切入無效,因為壓根就沒用代理對象去調用。
解決方案就是把service目標對象的A方法中對B的調用改成代理對象的調用,怎么獲取代理對象呢,AopContext.currentProxy()使用ThreadLocal保存了代理對象,因此在A方法中使用【((Service) AopContext.currentProxy()).B()】就能解決切入失效的問題。
另外,如果使用【AopContxt.currentProxy()】方法獲取當前代理對象需要在類上添加【@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)】注解。
"不在一起就不在一起吧,反正一輩子也沒多長。"