Spring AOP 內部呼叫失效解決方案
阿新 • • 發佈:2018-12-24
背景
前兩篇部落格採用AOP實現介面入參、返回結果的log列印和方法引數校驗。測試時發現一個問題,簡言之:
1、service中方法1設定AOP攔截,奏效
2、同service中方法2未設定AOP攔截,但在方法2中直接diao呼叫方法1,方法1的AOP攔截失效。
原因
通過debug發現,在方法2呼叫方法1時,this指向service物件本身(寫或不寫都指向本service),而非service的代理類。失效原因即在於此。
AOP原理:呼叫時,通過生成target物件的proxy代理類 ,基於代理類執行before增強後呼叫目標物件方法,後執行after增強,返回結果給呼叫方。當方法2直接呼叫update方法時,該service為service真實類,而非代理類,所以無法獲取代理執行AOP before 、after校驗。即直接呼叫目標物件,導致aop失效。
方案
this改為從applicationContext中獲取service來呼叫updateTrade方法即可。context中初始化均基於cglib來生成各service的代理物件,故改為從context中獲取代理物件後,方可執行AOP攔截。
總結
這個問題還是容易被忽略,尤其在@transaction註解時,使用 require、require_new等屬性,本身測試可能容易漏掉的case,如果不通過contaxt獲取service代理,而直接由service target去呼叫@transaction攔截方法,事務同樣會失效,所以還是需要引起重視。
多用多采坑多總結多收穫。很好。