Spring原始碼解析(十六)——AOP原理——獲取攔截器鏈——MethodInterceptor
* 3)、目標方法執行 ;
* 容器中儲存了元件的代理物件(cglib增強後的物件),這個物件裡面儲存了詳細資訊(比如增強器,目標物件,xxx);
* 1)、CglibAopProxy.intercept();攔截目標方法的執行
* 2)、根據ProxyFactory物件獲取將要執行的目標方法攔截器鏈;
* List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
* 1)、List<Object> interceptorList儲存所有攔截器 5
* 一個預設的ExposeInvocationInterceptor 和 4個增強器;
* 2)、遍歷所有的增強器,將其轉為Interceptor;
* registry.getInterceptors(advisor);
* 3)、將增強器轉為List<MethodInterceptor>;
* 如果是MethodInterceptor,直接加入到集合中
* 如果不是,使用AdvisorAdapter將增強器轉為MethodInterceptor;
* 轉換完成返回MethodInterceptor陣列;
* 3)、如果沒有攔截器鏈,直接執行目標方法;
* 攔截器鏈(每一個通知方法又被包裝為方法攔截器,利用MethodInterceptor機制)
* 4)、如果有攔截器鏈,把需要執行的目標物件,目標方法,
* 攔截器鏈等資訊傳入建立一個 CglibMethodInvocation 物件,
* 並呼叫 Object retVal = mi.proceed();
* 5)、攔截器鏈的觸發過程;
* 1)、如果沒有攔截器執行執行目標方法,或者攔截器的索引和攔截器陣列-1大小一樣(指定到了最後一個攔截器)執行目標方法;
* 2)、鏈式獲取每一個攔截器,攔截器執行invoke方法,每一個攔截器等待下一個攔截器執行完成返回以後再來執行;
* 攔截器鏈的機制,保證通知方法與目標方法的執行順序;
*
* 總結:
* 1)、 @EnableAspectJAutoProxy 開啟AOP功能
* 2)、 @EnableAspectJAutoProxy 會給容器中註冊一個元件 AnnotationAwareAspectJAutoProxyCreator
* 3)、AnnotationAwareAspectJAutoProxyCreator是一個後置處理器;
* 4)、容器的建立流程:
* 1)、registerBeanPostProcessors()註冊後置處理器;建立AnnotationAwareAspectJAutoProxyCreator物件
* 2)、finishBeanFactoryInitialization()初始化剩下的單例項bean
* 1)、建立業務邏輯元件和切面元件
* 2)、AnnotationAwareAspectJAutoProxyCreator攔截元件的建立過程
* 3)、元件建立完之後,判斷元件是否需要增強
* 是:切面的通知方法,包裝成增強器(Advisor);給業務邏輯元件建立一個代理物件(cglib);
* 5)、執行目標方法:
* 1)、代理物件執行目標方法
* 2)、CglibAopProxy.intercept();
* 1)、得到目標方法的攔截器鏈(增強器包裝成攔截器MethodInterceptor)
* 2)、利用攔截器的鏈式機制,依次進入每一個攔截器進行執行;
* 3)、效果:
* 正常執行:前置通知-》目標方法-》後置通知-》返回通知
* 出現異常:前置通知-》目標方法-》後置通知-》異常通知