Spring?AOP對嵌套方法不起作用的解決
Spring AOP對嵌套方法不起作用
今天在調(diào)研系統(tǒng)操作記錄日志時,好多教程都是借助于Spring AOP機制來實現(xiàn)。于是也采用這種方法來實現(xiàn)。在Service中的刪除日志方法上注解自定義的切點,但是執(zhí)行沒有生效。
代碼如下:
//嘗試刪除溢出日志 ? ? 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 = "操作日志緩存區(qū)溢出,系統(tǒng)自動清空緩存區(qū)") ? ? public void removeOverflowLog(int delNum) { ? ? ? ? custLogMapper.removeOverflowLog(delNum); ? ? }
在使用 Spring AOP 的時候,我們從 IOC 容器中獲取的 Service Bean 對象其實都是代理對象,而不是那些 Service Bean 對象本身,也就是說獲取的并不是被代理對象或代理目標(biāo)。當(dāng)我在自己的 Service 類中使用 this 關(guān)鍵字嵌套調(diào)用同類中的其他方法時,由于 this 關(guān)鍵字引用的并不是該 Service Bean 對象的代理對象,而是其本身,故 Spring AOP 是不能攔截到這些被嵌套調(diào)用的方法的。
要解決這個問題
最簡單的方法是把自身注入到自身,用注入的這個自身去調(diào)用本方法?;蛘吣阋部梢圆挥胹pring aop而是用aspectj weaving,倒是可以測底的解決該問題。我采用的是把自身注入到自身中。
? ? /** ? ? ?* 通過注入自身解決,Spring AOP嵌套調(diào)用不生效的問題 ? ? ?*/ ? ? @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、嵌套調(diào)用失效及解決
加入注解
@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)
獲取當(dāng)前代理的接口
public interface ICurrentAopProxyService<T> { ? ? default T getCurrentProxyService() { ? ? ? ? return (T) AopContext.currentProxy(); ? ? } }
需要嵌套調(diào)用的Service實現(xiàn)它
調(diào)用的時候改寫代碼
public SysMerchantVersion selectByMerchantId(Long merchantId) { return getCurrentProxyService().getOne(new QueryWrapper<SysMerchantVersion>() .lambda() .eq(SysMerchantVersion::getMerchantId, merchantId)); }
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java編程中快速排序算法的實現(xiàn)及相關(guān)算法優(yōu)化
這篇文章主要介紹了Java編程中快速排序算法的實現(xiàn)及相關(guān)算法優(yōu)化,快速排序算法的最差時間復(fù)雜度為(n^2),最優(yōu)時間復(fù)雜度為(n\log n),存在優(yōu)化的空間,需要的朋友可以參考下2016-05-05詳談Enumeration接口和Iterator接口的區(qū)別
下面小編就為大家?guī)硪黄斦凟numeration接口和Iterator接口的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-08-08SpringBoot項目docker容器部署實現(xiàn)
本文主要介紹了SpringBoot項目docker容器部署實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-03-03Java基礎(chǔ)之Unsafe內(nèi)存操作不安全類詳解
Java是面向?qū)ο笳Z言,在使用Java編程時,大多數(shù)情況下都不會直接操作內(nèi)存,而且Java也不提倡直接操作內(nèi)存,但是Java中到底有沒有可以直接操作內(nèi)存的工具類呢?有!Java中提供Unsafe類可以用來來直接操作內(nèi)存,文中詳細介紹了Unsafe內(nèi)存操作不安全類,需要的朋友可以參考下2021-06-06