Spring?AOP對(duì)嵌套方法不起作用的解決
Spring AOP對(duì)嵌套方法不起作用
今天在調(diào)研系統(tǒng)操作記錄日志時(shí),好多教程都是借助于Spring AOP機(jī)制來實(shí)現(xiàn)。于是也采用這種方法來實(shí)現(xiàn)。在Service中的刪除日志方法上注解自定義的切點(diǎn),但是執(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)自動(dòng)清空緩存區(qū)") ? ? public void removeOverflowLog(int delNum) { ? ? ? ? custLogMapper.removeOverflowLog(delNum); ? ? }
在使用 Spring AOP 的時(shí)候,我們從 IOC 容器中獲取的 Service Bean 對(duì)象其實(shí)都是代理對(duì)象,而不是那些 Service Bean 對(duì)象本身,也就是說獲取的并不是被代理對(duì)象或代理目標(biāo)。當(dāng)我在自己的 Service 類中使用 this 關(guān)鍵字嵌套調(diào)用同類中的其他方法時(shí),由于 this 關(guān)鍵字引用的并不是該 Service Bean 對(duì)象的代理對(duì)象,而是其本身,故 Spring AOP 是不能攔截到這些被嵌套調(diào)用的方法的。
要解決這個(gè)問題
最簡(jiǎn)單的方法是把自身注入到自身,用注入的這個(gè)自身去調(diào)用本方法?;蛘吣阋部梢圆挥胹pring aop而是用aspectj weaving,倒是可以測(cè)底的解決該問題。我采用的是把自身注入到自身中。
? ? /** ? ? ?* 通過注入自身解決,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實(shí)現(xiàn)它
調(diào)用的時(shí)候改寫代碼
public SysMerchantVersion selectByMerchantId(Long merchantId) { return getCurrentProxyService().getOne(new QueryWrapper<SysMerchantVersion>() .lambda() .eq(SysMerchantVersion::getMerchantId, merchantId)); }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringAop切入點(diǎn)execution表達(dá)式的深入講解
Spring AOP 可能會(huì)經(jīng)常使用 execution切入點(diǎn)指示符,下面這篇文章主要給大家介紹了關(guān)于SpringAop切入點(diǎn)execution表達(dá)式的相關(guān)資料,需要的朋友可以參考下2021-08-08SpringBoot下載文件的實(shí)現(xiàn)及速度對(duì)比
這篇文章主要介紹了SpringBoot下載文件的實(shí)現(xiàn)及速度對(duì)比,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12java異步編程的7種實(shí)現(xiàn)方式小結(jié)
異步處理的實(shí)現(xiàn)方式有很多種,常見多線程,消息中間件,發(fā)布訂閱的廣播模式,本文就詳細(xì)的介紹java異步編程的7種實(shí)現(xiàn)方式,感興趣的可以了解一下2023-03-03Java編程中快速排序算法的實(shí)現(xiàn)及相關(guān)算法優(yōu)化
這篇文章主要介紹了Java編程中快速排序算法的實(shí)現(xiàn)及相關(guān)算法優(yōu)化,快速排序算法的最差時(shí)間復(fù)雜度為(n^2),最優(yōu)時(shí)間復(fù)雜度為(n\log n),存在優(yōu)化的空間,需要的朋友可以參考下2016-05-05Java執(zhí)行shell命令的實(shí)現(xiàn)
本文主要介紹了Java執(zhí)行shell命令的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01詳談Enumeration接口和Iterator接口的區(qū)別
下面小編就為大家?guī)硪黄斦凟numeration接口和Iterator接口的區(qū)別。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08基于Bigdecimal科學(xué)計(jì)數(shù)問題
這篇文章主要介紹了基于Bigdecimal科學(xué)計(jì)數(shù)問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-06-06SpringBoot項(xiàng)目docker容器部署實(shí)現(xiàn)
本文主要介紹了SpringBoot項(xiàng)目docker容器部署實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-03-03Java基礎(chǔ)之Unsafe內(nèi)存操作不安全類詳解
Java是面向?qū)ο笳Z言,在使用Java編程時(shí),大多數(shù)情況下都不會(huì)直接操作內(nèi)存,而且Java也不提倡直接操作內(nèi)存,但是Java中到底有沒有可以直接操作內(nèi)存的工具類呢?有!Java中提供Unsafe類可以用來來直接操作內(nèi)存,文中詳細(xì)介紹了Unsafe內(nèi)存操作不安全類,需要的朋友可以參考下2021-06-06