spring原始碼解析-AOP原理
阿新 • • 發佈:2019-01-30
一、aop的入口
ProxyFactoryBean方式實現的入口
入口
1. ProxyFactoryBean實現了FactoryBean,所以入口在getObject方法。
2. initializeAdvisorChain方法初始化所有通知。
3. getSingletonInstance中呼叫getProxy(createAopProxy())建立代理。
自動代理方式入口(DefaultAdvisorAutoProxyCreator ,
BeanNameAutoProxyCreator )
以BeanNameAutoProxyCreator 為例
入口
1. 它們都繼承了AbstractAutoProxyCreator, AbstractAutoProxyCreator實現了BeanPostProcessor介面, 當spring的bean呼叫getBean初始化前後會回撥該介面postProcessAfterInitialization的方法
2. BeanNameAutoProxyCreator.getAdvicesAndAdvisorsForBean方法中匹配當前Bean是否需要被攔截
3. createProxy建立代理。
使用aop:config配置
入口
1.在AopNamespaceHandler中,registerBeanDefinitionParser("config", new ConfigBeanDefinitionParser())註冊ConfigBeanDefinitionParser解析器。
2. ConfigBeanDefinitionParser.parse方法,首先呼叫configureAutoProxyCreator方法,註冊AspectJAwareAdvisorAutoProxyCreator。
3. AspectJAwareAdvisorAutoProxyCreator的父類AbstractAutoProxyCreator實現了BeanPostProcessor介面, 當spring的bean呼叫getBean初始化前後會回撥該介面。
獲取advisor
1. parsePointcut方法解析<aop:pointcut>標籤,裝載定義的切點。
2. parseAdvisor方法解析<aop:advisor>標籤,將會裝載出advisor.
3. parseAspect則是對應<aop:aspct>方式。
使用<aop:aspectj-autoproxy>, aspectj註解方式
入口
1. 對於標籤的解析在AopNamespaceHandler中,registerBeanDefinitionParser("aspectj-autoproxy", new AspectJAutoProxyBeanDefinitionParser())註冊AspectJAutoProxyBeanDefinitionParser解析器。
2. AspectJAutoProxyBeanDefinitionParser.parse()方法, 呼叫AopNamespaceUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary,首先建立AnnotationAwareAspectJAutoProxyCreator的BeanDefinition, 呼叫useClassProxyingIfNecessary解析proxy-target-class解析expose-proxy和proxy-target-class屬性,呼叫registerComponentIfNecessary方法註冊BeanDefinition。
3. 真正的入口就在AnnotationAwareAspectJAutoProxyCreator, 它的父類AbstractAutoProxyCreator實現了BeanPostProcessor介面, 當spring的bean呼叫getBean初始化前後會回撥該介面。
獲取advisor
4. AbstractAutoProxyCreator.postProcessAfterInitialization方法會被回撥,其中呼叫wrapIfNecessary方法,這裡面獲取所有的通知,並建立代理 。
5.呼叫父類AbstractAdvisorAutoProxyCreator.getAdvicesAndAdvisorsForBean方法獲取通知。findCandidateAdvisors獲取所有通知,並呼叫findAdvisorsThatCanApply匹配出合適的通知返回。
6. findCandidateAdvisors方法,會由子類來實現 ,AnnotationAwareAspectJAutoProxyCreator中獲取了所有註解生成的通知,AbstractAdvisorAutoProxyCreator獲取在配置檔案中的定義的通知。
7.this.aspectJAdvisorsBuilder.buildAspectJAdvisors()生成aspect註解定義的通知。其中根據ReflectiveAspectJAdvisorFactory.getAdvisors獲取。
8. getAdvisor獲取普通的通知,getPointcut獲取切點資訊,然後例項化InstantiationModelAwarePointcutAdvisorImpl物件,返回。
9.在InstantiationModelAwarePointcutAdvisorImpl構造方法中,完成屬性的注入後,會呼叫ReflectiveAspectJAdvisorFactory.instantiateAdvice方法,根據不同的註解的型別生成不同通知。
生成代理
10. 還是在wrapIfNecessary方法中,獲取到所有advisor後,會呼叫createProxy生成代理,並把通知插入到代理的攔截器中。
11. 例項化一個ProxyFactory,並設定通知器,target等屬性,proxyFactory.getProxy獲取代理。
12.createAopProxy()方法會根據相關策略,生成JdkDynamicAopProxy或者ObjenesisCglibAopProxy。
13.使用jdk生成代理時,在InvocationHandler的回撥方法invoke中插入通知。
. AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice生成方法的攔截器鏈
.ReflectiveMethodInvocation.proceed()方法開始執行攔截器呼叫,呼叫interceptor.invoke執行具體的Advice。並在advice的中會呼叫MethodInvocation.proceed形成鏈式呼叫。
14.使用Cglib生成代理時。
呼叫getCallbacks建立回撥,為每個方法建立回撥,例項化FixedChainStaticTargetInterceptor,封裝攔截器。
FixedChainStaticTargetInterceptor.intercept方法中執行回撥,併成其中呼叫invocation.proceed()開始攔截器的呼叫。