AOP原始碼解析
一、AOP整體流程介紹
1、spring 例項化單例bean,第一次呼叫後置處理器,解析切面@Aspect ,解析切面中的 @Pointcut @befor @after等,生成advisors(說明 一個 @before + 切點 生成一個advisor)
1.1 org.springframework.context.support.AbstractApplicationContext#refresh() 方法
1.2 org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization(beanFactory); // 例項化我們剩餘的單例項bean.
1.3 org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons
1.4 org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean 建立bean方法
1.5 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean()真正建立bean的方法
Object bean = resolveBeforeInstantiation(beanName, mbdToUse); 在此處呼叫 第一個後置處理器(InstantiationAwareBeanPostProcessor),解析切面,生成advisors ,進行快取
1.6 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation
InstantiationAwareBeanPostProcessor 後置處理器實現了 BeanpostProcessor ,有2個介面
方法1:postProcessBeforeInitialization 在bean初始化之前呼叫,用於解析切面,生成advisors
方法2:postProcessAfterInitialization bean初始化之後呼叫,用於 生成代理物件
1.7 org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip
1.8 org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
1.9 org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors 解析切面類,構建advisors,存放到快取中
2.0 org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisor -》 new InstantiationModelAwarePointcutAdvisorImp
二、AOP 觸發時機說明
1、在沒有迴圈依賴的情況下,AOP生成代理 是在 bean的初始化完成以後(屬性賦值之後)
1.1 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean()
1.2 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
1.3 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization 這裡是bean的後置處理器的第九次呼叫,aop和事務都會在這裡生存代理物件
1.4 org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
根據當前bean找到匹配的 (一)中生成的advisor,匹配到了說明需要生成代理物件
1.5 org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy 建立代理工廠,
根據 當前bean是否實現介面,,是否設定ProxyTargetClass 屬性 ,判斷生成 jdk的代理工廠,還是cglib的代理工廠
若我們 ProxyTargetClass 指定為false 且代理類是接口才會走jdk代理 否在我們還是cglib代理 ;;ProxyTargetClass 預設為false;
1.6 JdkDynamicAopProxy ->Proxy.newProxyInstance(classLoader, proxiedInterfaces, this); 生成代理物件
CglibAopProxy 生成代理
2、存在迴圈依賴的情況下,AOP生成代理 是在 bean 例項化以後
三、代理物件呼叫方法,進行增強
以jdk動態代理為例:
1. org.springframework.aop.framework.JdkDynamicAopProxy#invoke
1.1 判斷哪些方法不需要增強 (equals、hashcode 等方法無需增強)
1.2 獲取到目標物件
1.3 找到適配到當前目標物件的所有的advisors;如果沒有,,直接執行目標物件方法;如果有 先執行增強方法
1.4 將目標物件的所有advisors 構造成一個 攔截器鏈一次執行, (說明:此處 使用的是 責任鏈模式) 這裡用了責任鏈的設計模式,遞迴呼叫排序好的攔截器鏈
執行順序: @AfterTrrowing @AfterReturning @After @Before
說明:jdk動態代理 本類方法 A 呼叫 B 不會走動態代理,,可以設定 expose屬性