這節介紹Spring AOP。關於Spring AOP的名字就很少作介紹了,網上有不少對AOP的解釋。spring
1.1 切面(Aspect)express
切面是一個關注點的模塊化,這個關注點多是橫切多個對象;微信
1.2 鏈接點(Join Point)框架
鏈接點是指在程序執行過程當中某個特定的點,好比某方法調用的時候或者處理異常的時候;模塊化
1.3 通知(Advice)post
指在切面的某個特定的鏈接點上執行的動做。Spring切面能夠應用5種通知:ui
前置通知(Before):在目標方法或者說鏈接點被調用前執行的通知;spa
後置通知(After):指在某個鏈接點完成後執行的通知;prototype
返回通知(After-returning):指在某個鏈接點成功執行以後執行的通知;代理
異常通知(After-throwing):指在方法拋出異常後執行的通知;
環繞通知(Around):指包圍一個鏈接點通知,在被通知的方法調用以前和以後執行自定義的方法。
1.5 切點(Pointcut)
指匹配鏈接點的斷言。通知與一個切入點表達式關聯,並在知足這個切入的鏈接點上運行,例如:當執行某個特定的名稱的方法。
1.4 引入(Introduction)
引入也被稱爲內部類型聲明,聲明額外的方法或者某個類型的字段。
1.5 目標對象(Target Object)
目標對象是被一個或者多個切面所通知的對象。
1.6 AOP代理(AOP Proxy)
AOP代理是指AOP框架建立的對象,用來實現切面(包括通知方法等功能)
1.7 織入(Wearving)
指把切面鏈接到其餘應用出程序類型或者對象上,並建立一個被通知的對象。或者說造成代理對象的方法的過程。
AOP的通常配置以下:
以前BeanDefiniton解析那節提到,XML的解析在classpath下META-INF的spring.handlers裏。查看spring-aop模塊能夠看到以下配置
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
該處理類以下
能夠看到配置文件的處理交由
org.springframework.aop.config.ConfigBeanDefinitionParser
來處理,該類實現了BeanDefinitionParser接口,該接口的實現內容以下:
該方法主要完成兩件事,
註冊AspectJAwareAdvisorAutoProxyCreator
解析pointcut,advisor,aspect節點
下面重點看下這兩點
AspectJAwareAdvisorAutoProxyCreator的繼承結構以下:
該類在父類AbstractAutoProxyCreator那實現了接口SmartInstantiationAwareBeanPostProcessor,AbstractAutoProxyCreator主要實現了 方法
postProcessBeforeInstantiation
和方法
postProcessAfterInitialization
postProcessBeforeInstantiation會在bean實例化前執行,若是返回非null,則不會實例化該bean。 postProcessAfterInitialization會在bean實例化並初始化後執行,若是返回非null,則使用該實例,不然使用原Bean對象。即對目標對象的包裝能夠發生在實例化前,也能夠發生在初始化後。
如上圖示:
在beanName爲空或者目標類不包含該beanName的前提下,若是該bean是通知執行對象(advisedBeans)則不進行代理;若是爲基礎類且須要跳過則不進行代理,同時會將其標記爲非通知執行對象。
若是該beanName設置了TargetSource,則調用createProxy方法爲該beanName建立代理對象,並將其進行標記,存於targetSourceBeans字段中。這裏調用createProxy方法前會調用getAdvicesAndAdvisorsForBean方法獲取該bean上設置的通知點。
該方法主要調用了wrapIfNecessary,先判斷初始化後的對象是否須要進行代理,若是須要進行代理,也是同上面同樣調用createProxy方法,並調前前會調用getAdvicesAndAdvisorsForBean方法獲取該bean上設置的通知點,以下:
該過程會將已經初始化後的bean包裝爲SingletonTargetSource傳入。
該方法的具體實如今其子類AbstractAdvisorAutoProxyCreator中,內容以下
主要調用了findEligibleAdvisors方法,若是該方法返回爲空,則返回DO<u> </u>NOT<u> </u>PROXY.
findEligibleAdvisors方法的處理流程爲:
找出全部實現了Advisors接口的Bean(配置爲Advisor的Bean將會被包裝爲DefaultBeanFactoryPointcutAdvisor註冊到Spring中;配置爲Advice的將會被包裝爲AspectJPointcutAdvisor註冊到Spring中)
從全部Advisors中找出可以應用在beanClass上的bean,主要判斷Advisors是否命中PointCut的規則
根據Order對Advisor進行排序
如上爲createProxy的主要內容,主要是使用相關的Advisor列表和TargetSource生成ProxyFactory對象,委託爲ProxyFactory進行代理的包裝。主要調用ProxyFacotry的getProxy方法, 該過程會在後面進行講解.
回到ConfigBeanDefinitionParser的parse過程,在註冊完AspectJAwareAdvisorAutoProxyCreator後即是XML配置項的解析,主要包括:pointcut,advisor和aspect節點。
ProxyFactory的結構以下:
aspectj-autoproxy提供自動完成建立代理織入切面的功能,可以經過配置註解Aspectj織入切面。aspectj-autoproxy 有一個proxy-target-class屬性,默認爲false,表示使用jdk動態代理織入加強,當配爲true時,表示使用CGLib動態代理技術織入加強。不過即便proxy-target-class設置爲false,若是目標類沒有聲明接口,則spring將自動使用CGLib動態代理。根據上面的介紹,該動能由AspectJAutoProxyBeanDefinitionParser提供,主要向Spring註冊了AnnotationAwareAspectJAutoProxyCreator類。
AnnotationAwareAspectJAutoProxyCreator繼承自AspectJAwareAdvisorAutoProxyCreator,只擴展了findCandidateAdvisors方法,將Advisor的搜索範圍擴大到了註解上,使之能夠用註解進行配置,具體委託給了BeanFactoryAspectJAdvisorsBuilderAdapter的BeanFactoryAspectJAdvisorsBuilderAdapter實現。
更多原創內容請搜索微信公衆號:啊駝(doubaotaizi)