Spring AOP對嵌套方法不起作用的解決
Spring AOP對嵌套方法不起作用
今天在調研系統操作記錄日志時,好多教程都是借助於Spring AOP機制來實現。於是也采用這種方法來實現。在Service中的刪除日志方法上註解自定義的切點,但是執行沒有生效。
代碼如下:
//嘗試刪除溢出日志 public synchronized void tryDelOverflowLog() { logNum++; if (logNum - LogConst.MAX_NUM > 0) { int delNum = logNum - LogConst.MAX_NUM + LogConst.EXTRA_NUM; logNum -= delNum; removeOverflowLog(delNum); } } //日志溢出後,刪除最新入庫的日志 @ServiceLog(type = LogConst.TYPE_LOG_RECORD, description = "操作日志緩存區溢出,系統自動清空緩存區") public void removeOverflowLog(int delNum) { custLogMapper.removeOverflowLog(delNum); }
在使用 Spring AOP 的時候,我們從 IOC 容器中獲取的 Service Bean 對象其實都是代理對象,而不是那些 Service Bean 對象本身,也就是說獲取的並不是被代理對象或代理目標。當我在自己的 Service 類中使用 this 關鍵字嵌套調用同類中的其他方法時,由於 this 關鍵字引用的並不是該 Service Bean 對象的代理對象,而是其本身,故 Spring AOP 是不能攔截到這些被嵌套調用的方法的。
要解決這個問題
最簡單的方法是把自身註入到自身,用註入的這個自身去調用本方法。或者你也可以不用spring aop而是用aspectj weaving,倒是可以測底的解決該問題。我采用的是把自身註入到自身中。
/** * 通過註入自身解決,Spring AOP嵌套調用不生效的問題 */ @Autowired private ApplicationContext applicationContext; private LogService self; @PostConstruct private void init() { self = (LogService) applicationContext.getBean("logService"); } //嘗試刪除溢出日志 public synchronized void tryDelOverflowLog() { logNum++; if (logNum - LogConst.MAX_NUM > 0) { int delNum = logNum - LogConst.MAX_NUM + LogConst.EXTRA_NUM; logNum -= delNum; self.removeOverflowLog(delNum); } }
Spring AOP、嵌套調用失效及解決
加入註解
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
獲取當前代理的接口
public interface ICurrentAopProxyService<T> { default T getCurrentProxyService() { return (T) AopContext.currentProxy(); } }
需要嵌套調用的Service實現它
調用的時候改寫代碼
public SysMerchantVersion selectByMerchantId(Long merchantId) { return getCurrentProxyService().getOne(new QueryWrapper<SysMerchantVersion>() .lambda() .eq(SysMerchantVersion::getMerchantId, merchantId)); }
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- 獲取Spring的上下文環境ApplicationContext的最簡單方式
- 關於spring中單例Bean引用原型Bean產生的問題及解決
- 詳解Spring bean的註解註入之@Autowired的原理及使用
- java的main方法中調用spring的service方式
- SpringBoot項目如何將Bean註入到普通類中