四,Spring AOP攔截器調(diào)用的實現(xiàn)
1. 設(shè)計原理
- 在Spring AOP通過JDK的Proxy方式或者CGLIB方式生成代理對象的時候,相關(guān)的攔截器已經(jīng)配置到代理對象中去了。
- 設(shè)置攔截器回調(diào)
- 通過JDK的Proxy方式生成代理對象:通過InvocationHandler設(shè)置攔截器回調(diào)
- 通過CGLIB方式生成代理對象:根據(jù)CGLIB使用要求,通過DynamicAdvisedInterceptor來完成回調(diào)。
2. JdkDynamicAopProxy的invoke攔截
- 通過實現(xiàn)InvocationHandler接口中的invoke方法,來完成對目標對象方法調(diào)用的攔截或者說功能增強的工作。
- 創(chuàng)建ReflectiveMethodInvocation對象來完成對AOP功能實現(xiàn)的封裝
-
invoke方法中對攔截器進行配置的代碼:
JdkDynamicAopProxy的invoke攔截.png
3. Cglib2AopProxy的intercept攔截
- 在對于AOP的攔截調(diào)用,回調(diào)在DynamicAdvisedInterceptor對象中實現(xiàn),具體實現(xiàn)是在DynamicAdvisedInterceptor中的intercept方法中
- 創(chuàng)建CglibMethodInvocation對象來完成攔截器鏈的調(diào)用(JdkDynamicAopProxy通過構(gòu)造ReflectiveMethodInvocation對象來完成這個功能)
-
DynamicAdvisedInterceptor的intercept部分代碼:
Cglib2AopProxy的intercept攔截.png
4. 目標對象方法的調(diào)用
- 使用JdkDynamicAopProxy的代理對象:通過AopUtils使用反射機制在AopUtils.invokejoinpointUsingReflection的方法中實現(xiàn)
- 使用Cglib2AopProxy的代理對象:通過CGLIB的MethodProxy對象直接完成
5. AOP攔截器鏈的調(diào)用
-
兩種方式對攔截器的調(diào)用都是在ReflectiveMethodInvocation中通過proceed方法實現(xiàn)。在proceed方法中逐個實現(xiàn)攔截器的攔截方法。每個攔截器在執(zhí)行之前,需要對代理方法完成一個匹配判斷(即Pointcut切點中需要進行matches匹配過程)。
攔截器的運行.png
6. 配置通知器
- proceed方法中interceptorOrInterceptionAdvice鏈來自interceptorsAndDynamicMethodMatchers持有的List的一個元素
- 而List中的攔截器元素在JDKDynamicAopProxy中的invoke方法或Cglib2AopProxy中DynamicAdvisedInterceptor的intercept回調(diào)中實現(xiàn),并且我們可以從中看出獲取interceptors的操作在advised對象完成。
-
這個advised是一個AdvisedSupport對象
AdvisedSupport取得攔截器.png
-
DefaultAdvisorChainFactory:生成通知器鏈的工廠,實現(xiàn)了interceptor鏈的獲取過程
DefaultAdvisorChainFactory生成攔截器鏈.png- 先設(shè)置一個List,長度為配置的通知器的個數(shù)。該配置即為XML中對ProxyFactory做的interceptNames屬性的配置
- AdvisorAdapterRegistry:實現(xiàn)攔截器的注冊,對從ProxyFactoryBean配置中得到的同志進行適配,從而獲得相應(yīng)的攔截器
- 攔截器適配和注冊過程完成以后,List中的攔截器會被JDK生成的AopProxy代理對象的invoke方法或者CGLIB代理對象的intercept攔截方法取得,并啟動攔截器的invoke調(diào)用,最終觸發(fā)通知的切面增強
-
在ProxyFactoryBean的getObject方法中對advisor進行初始化
在攔截器鏈的初始化中獲取advisor通知器.png
通過對IOC容器的一個getBean回調(diào),得到配置好的advisor通知器
-
以DefaultListableBeanFactory作為IOC容器時,基類AbstractAutowireCapableBeanFactory有一個對Bean進行初始化的initializeBean方法。在這個方法中,判斷Bean類型是否實現(xiàn)BeanFactoryAware接口
Bean類型是否實現(xiàn)BeanFactoryAware接口.png - 實現(xiàn)一個接口方法setBeanFactory,設(shè)置的this對象表示Bean所在IOC容器,一般指DefaultListableBeanFactory對象。
- 得到這個設(shè)置好的BeanFactory以后,ProxyFactoryBean就可以通過回調(diào)容器的getBean去獲取配置在Bean定義文件中的通知器,獲取通知器就是向IOC容器回調(diào)getBean(依賴注入)的過程。
- 在調(diào)用時,ProxyFactoryBean給出通知器的名字,這些名字都是在interceptorNames的List中配置好的,在IOC對FactoryBean進行依賴注入時,會直接注入到FactoryBean的interceptorNames屬性中。完成這個過程后,ProxyFactoryBean就獲得了配置的通知器,為完成切面增強做好了準備。
7. Advice通知的實現(xiàn)
- DefaultAdvisorChainFactory(負責(zé)生成攔截器鏈)使用GlobalAdvisorAdapterRegistry得到AOP攔截器
-
GlobalAdvisorAdapterRegistry的實現(xiàn):單件設(shè)計模式,保證所要生成對象的唯一性
單件設(shè)計模式.png
- 配置一個靜態(tài)的final變量instance,使得對象在加載類的時候就生成了
- 抽象類,不能被實例化,保證instance對象的唯一性
- 使用instance對象時,通過靜態(tài)方法getInstance方法完成,保證instance唯一對象的獲取
- DefaultAdvisorAdapterRegistry設(shè)置了一系列adapter適配器,為Spring AOP的advice提供編織能力。
- 以MethodBeforeAdviceAdapter為例,把advice通知從通知器中取出,通過MethodBeforeAdviceInterceptor對象把取得的advice通知包裝起來。在MethodBeforeAdviceInterceptor方法中,會先調(diào)用advice的before方法,在方法調(diào)用之前完成通知增強。
8. ProxyFactory實現(xiàn)AOP
上面的分析著重講解了以ProxyFactoryBean為例Spring AOP的實現(xiàn)原理,除此之外,ProxyFactory也可以實現(xiàn)Spring AOP,而且原理也差不多,只不過后者需要編程式地完成AOP應(yīng)用的設(shè)置。

ProxyFactory.png







