【Spring源碼】24.AOP之代理執(zhí)行時匹配方法需要的切面

接著前文繼續(xù)講

4. 切面的匹配

這里JdkDynamicAopProxy類的AdvisedSupport advised屬性里的proxyFactory.advisors只是符合該類的。

是用來判斷這個類的bean需不需要被代理,所以有一個方法被匹配,就需要,和具體的方法并沒有綁定關系。

那么接下來,就要符合該類的advisors從中找到 匹配該方法的advisors對象。

image.png

有個方法與匹配advisors的緩存,第一次進來沒有緩存,走匹配邏輯

image.png

接下來就需要每個Advisor對象,去調(diào)用它的PointCut對象的 ClassFilter來匹配類,以及MethodMatcher對象來匹配方法

ClassFilter來匹配類

image.png

注意這個判斷前面有個config.isPreFiltered()代理,會預先存儲之前 判斷該bean需不需要被代理時,是否與類型匹配,這里是永遠為true的,

因為JdkDynamicAopProxy類的AdvisedSupport advised屬性里的proxyFactory.advisors都是與該類匹配并存儲到這里的。

image.png

這個屬性的賦值為true是在創(chuàng)建代理對象的時候

image.png

這里advisorsPreFiltered()判斷是否需要復制,會走到AbstractAutoProxyCreator的子類,AbstractAdvisorAutoProxyCreator,它的advisorsPreFiltered()是為true的,需要把ProxyFactory的preFiltered屬性賦值為true

image.png

所以這里,是不用調(diào)用Advisor的PointCut對象的ClassFilter對象的matches(class)來判斷 切面是否與類匹配的。

MethodMatcher.matches()匹配方法

接下來直接調(diào)用 Advisor的PointCut對象的 MethodMatcher.matches()判斷是否與當前正在執(zhí)行的方法匹配

image.png

這里和 判斷該bean需不需要被代理時,過濾spring容器內(nèi)所有的advisor一樣,會進行aspectj的方法表達式進行匹配,這里就不贅述了。

匹配成功,加入容器

匹配成功,取出Advisor對象的advise切面對象 加入容器

image.png

這里注意取出的切面 數(shù)組 為MethodInterceptor[], 前面創(chuàng)建Advisor的advise對象講過, aop注解與Advice實現(xiàn)類的關系

注解 Aavice實現(xiàn)類
@Around AspectJAroundAdvice
@Before AspectJMethodBeforeAdvice
@After AspectJAfterAdvice
@AfterReturning AspectJAfterReturningAdvice
@AfterThrowing AspectJAfterThrowingAdvice

AspectJAroundAdvice,AspectJAfterThrowingAdvice,AspectJAfterAdvice這三個類是實現(xiàn)MethodInterceptor接口的

AspectJAfterReturningAdvice和AspectJAfterThrowingAdvice 適配成 MethodInterceptor接口類型

,AspectJAfterReturningAdvice和AspectJMethodBeforeAdvice類是沒有實現(xiàn) MethodInterceptor接口的,這里aop代理過程中為了 統(tǒng)一調(diào)用的邏輯,會把AspectJAfterReturningAdvice

和AspectJAfterThrowingAdvice類進行適配,我們來具體看一下

image.png

如果advisor的advice對象是如果是MethodInterceptor類型的,如: AspectJAroundAdvice/AspectJAfterAdvice//AspectJAfterThrowingAdvice,直接加入容器

如果不是那么用適配器 來匹配并且適配。

這里DefaultAdvisorAdapterRegistry類預制了三種 適配器,我們只需要關注適配AspectJMethodBeforeAdvice AspectJAfterReturningAdvice這兩種的MethodBeforeAdviceAdapter和AfterReturningAdviceAdapter這兩個

image.png

遍歷所有的 切面適配器,調(diào)用它的supportsAdvice方法判斷是否支持,支持的話則進行適配,這里我們就看MethodBeforeAdviceAdapter類

MethodBeforeAdviceAdapter

image.png

MethodBeforeAdviceAdapter.supportsAdvice

其實就是一個類型判斷,判斷切面類是否是MethodBeforeAdvice,之前看了 ,@Before注解生成的切面類就是 MethodBeforeAdvice

image.png

MethodBeforeAdviceAdapter.getInterceptor

如果適配類supportsAdvice表示支持的話,那么就會調(diào)用getInterceptor來進行適配

MethodBeforeAdviceAdapter.getInterceptor()

image.png

創(chuàng)建了一個MethodBeforeAdviceInterceptor類,包裝MethodBeforeAdviced對象

然后由MethodBeforeAdviceInterceptor去實現(xiàn)MethodInterceptor接口,并在invoke方法 ,調(diào)用 MethodBeforeAdviced對象的before來執(zhí)行代理邏輯,并增加傳遞 執(zhí)行鏈的代碼,高!

image.png

AfterReturningAdviceAdapter源碼

image.png

加入容器

最終這五種切面類型全部 都會是MethodInterceptor類型,加入要執(zhí)行的切面容器

image.png

然后遍歷完所有類,該方法需要執(zhí)行的所有切面都會被返回出來

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容