五、AOP原理-獲取攔截器鏈-MethodInterceptor(適配器模式+鏈式調用調用過程)

容器Bean創建前後,尤其在對象創建之後,尤其是在目標對象創建之後,需要被切入需要增強的組件。

容器中生成的對象即爲代理對象,那麼代理對象前置通知、目標方法、後置通知、返回通知、異常通知如何有序執行

1)、CglibAopProxy.intercept();攔截目標方法的執行

CglibAopProxy.DynamicAdvisedInterceptor.intercept(Object, Method, Object[], MethodProxy)

2)、根據ProxyFactory對象獲取將要執行的目標方法攔截器鏈;

 2-1、List<Object> interceptorList保存所有攔截器


              一個默認的ExposeInvocationInterceptor 和 4個增強器;

org.springframework.aop.framework.DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(Advised, Method, Class<?>)

判斷是否是需要切面的增強器,給增強器轉爲Interceptor

for (Advisor advisor : config.getAdvisors()) {}\

如果是MethodInterceptro直接轉過來,如果不是通過適配器,將advisor通過Adapter適配器,將advisor轉爲Interceptor.


 2-2、遍歷所有的增強器,將其轉爲Interceptor【適配器模式】;


 registry.getInterceptors(advisor);

異常通知 AspectJAfterThrowingAdvice 是MethodInterceptor

AspectJAfterThrowingAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice 

後置通知AspectJAfterAdvice是MethodInterceptor

public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor, AfterAdvice

========================================================================================

返回通知 AspectJAfterReturningAdvice 不是MethodInterceptor,通過AfterReturningAdviceAdapter

AspectJAfterReturningAdvice extends AbstractAspectJAdvice implements AfterReturningAdvice, AfterAdvice

前置通知AspectJMethodBeforeAdvice不是MethodInterceptor

public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice


 通過Advisor獲取advice

2-3、將增強器轉爲List<MethodInterceptor>;

 

  •  如果是MethodInterceptor,直接加入到集合中
  • 如果不是,使用AdvisorAdapter將增強器轉爲MethodInterceptor;
  •  轉換完成返回MethodInterceptor數組;

3)、如果沒有攔截器鏈,直接執行目標方法;

攔截器鏈(每一個通知方法又被包裝爲方法攔截器,利用MethodInterceptor機制)

 

4)、如果有攔截器鏈,把需要執行的目標對象,目標方法,攔截器鏈等信息傳入創建一個 CglibMethodInvocation 對象【鏈式調用】


調用 Object retVal =  mi.proceed();
 retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();

攔截器鏈的觸發過程;

org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor.intercept(Object, Method, Object[], MethodProxy)

 

 


           4-1、如果沒有攔截器執行執行目標方法,或者攔截器的索引和攔截器數組-1大小一樣(指定到了最後一個攔截器)執行目標方法;

 


           4-2、鏈式獲取每一個攔截器,攔截器執行invoke方法,每一個攔截器等待下一個攔截器執行完成返回以後再來執行;
             攔截器鏈的機制,保證通知方法與目標方法的執行順序;

 

5)、攔截器鏈的觸發過程;


 *             1)、如果沒有攔截器執行執行目標方法,或者攔截器的索引和攔截器數組-1大小一樣(指定到了最後一個攔截器)執行目標方法;
 *             2)、鏈式獲取每一個攔截器,攔截器執行invoke方法,每一個攔截器等待下一個攔截器執行完成返回以後再來執行;
 *                 攔截器鏈的機制,保證通知方法與目標方法的執行順序;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章