1. 程式人生 > >Spring AOP 內部呼叫失效解決方案

Spring AOP 內部呼叫失效解決方案

背景

前兩篇部落格採用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攔截方法,事務同樣會失效,所以還是需要引起重視。

多用多采坑多總結多收穫。很好。