Spring AOP

 這節介紹Spring AOP。關於Spring AOP的名字就很少作介紹了,網上有不少對AOP的解釋。spring

1. 概念術語

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)

 指把切面鏈接到其餘應用出程序類型或者對象上,並建立一個被通知的對象。或者說造成代理對象的方法的過程。

2. 入口

 AOP的通常配置以下:

file

 以前BeanDefiniton解析那節提到,XML的解析在classpath下META-INF的spring.handlers裏。查看spring-aop模塊能夠看到以下配置

http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler

 該處理類以下

file

 能夠看到配置文件的處理交由

org.springframework.aop.config.ConfigBeanDefinitionParser

來處理,該類實現了BeanDefinitionParser接口,該接口的實現內容以下:

file

該方法主要完成兩件事,

  • 註冊AspectJAwareAdvisorAutoProxyCreator

  • 解析pointcut,advisor,aspect節點

 下面重點看下這兩點

3. AspectJAwareAdvisorAutoProxyCreator

 AspectJAwareAdvisorAutoProxyCreator的繼承結構以下:

file

該類在父類AbstractAutoProxyCreator那實現了接口SmartInstantiationAwareBeanPostProcessor,AbstractAutoProxyCreator主要實現了 方法

postProcessBeforeInstantiation

和方法

postProcessAfterInitialization

  postProcessBeforeInstantiation會在bean實例化前執行,若是返回非null,則不會實例化該bean。 postProcessAfterInitialization會在bean實例化並初始化後執行,若是返回非null,則使用該實例,不然使用原Bean對象。即對目標對象的包裝能夠發生在實例化前,也能夠發生在初始化後。

3.1. postProcessBeforeInstantiation

file

 如上圖示:

  • 在beanName爲空或者目標類不包含該beanName的前提下,若是該bean是通知執行對象(advisedBeans)則不進行代理;若是爲基礎類且須要跳過則不進行代理,同時會將其標記爲非通知執行對象。

  • 若是該beanName設置了TargetSource,則調用createProxy方法爲該beanName建立代理對象,並將其進行標記,存於targetSourceBeans字段中。這裏調用createProxy方法前會調用getAdvicesAndAdvisorsForBean方法獲取該bean上設置的通知點。

3.2. postProcessAfterInitialization

 該方法主要調用了wrapIfNecessary,先判斷初始化後的對象是否須要進行代理,若是須要進行代理,也是同上面同樣調用createProxy方法,並調前前會調用getAdvicesAndAdvisorsForBean方法獲取該bean上設置的通知點,以下:

file

該過程會將已經初始化後的bean包裝爲SingletonTargetSource傳入。

3.3. getAdvicesAndAdvisorsForBean

 該方法的具體實如今其子類AbstractAdvisorAutoProxyCreator中,內容以下

file

主要調用了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進行排序

3.4. createProxy

file

 如上爲createProxy的主要內容,主要是使用相關的Advisor列表和TargetSource生成ProxyFactory對象,委託爲ProxyFactory進行代理的包裝。主要調用ProxyFacotry的getProxy方法, 該過程會在後面進行講解.

4. 節點解析

 回到ConfigBeanDefinitionParser的parse過程,在註冊完AspectJAwareAdvisorAutoProxyCreator後即是XML配置項的解析,主要包括:pointcut,advisor和aspect節點。

  • pointcut:爲每一個pointcut配置註冊一個AspectJExpressionPointcut,範圍爲prototype的Bean,會設置expression屬性
  • advisor:爲每一個advisor配置註冊一個DefaultBeanFactoryPointcutAdvisor,須要關聯一個advice,經過advice-ref指定對應的Bean;以及關聯一個pointcut
  • aspect:包含一個或者多個advice節點已經pointcut節點,pointcut的解析同以前的相似,主要是advice節點。advice類別分爲
    • before:執行前置通知
    • after:執行後置通知
    • after-returning:執行返回通知
    • after-throwing:執行異常通知
    • around:執行迴環通知 對於每一個advice都會包裝爲一個AspectJPointcutAdvisor

5. ProxyFacotry

 ProxyFactory的結構以下: file

  • ProxyFactory主要對ProxyCreatorSupport進行了封裝,用於設置TargetSource和各攔截器接口。
  • ProxyCreatorSupport繼承自AdvisedSupport,AdvisedSupport自己持有建立代理的各參數。同時引用了AopProxyFactory,將代理的建立動做委託給了AopProxyFactory。調用ProxyFactory的createAopProxy方法實際調用了AopProxyFactory的createAopProxy方法,該方法須要傳入一個AdvisedSupport對象,即ProxyFactory自己。
  • DefaultAopProxyFactory決定使用哪一種方式來建立代理,可選方式爲Jdk動態代理或者Cglib,內容以下: file

6. aspectj-autoproxy

 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實現。

file

更多原創內容請搜索微信公衆號:啊駝(doubaotaizi)

相關文章
相關標籤/搜索