容器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方法,每一個攔截器等待下一個攔截器執行完成返回以後再來執行;
* 攔截器鏈的機制,保證通知方法與目標方法的執行順序;