咱們若是善用spring框架的源碼設計思路,其實能夠寫出低耦合、高內聚、兼顧靈活性和擴展性較好的優雅代碼,尤爲是在作框架或組件設計的時候。今天咱們就來分享一個能讓咱們代碼變得優雅的spring核心模塊-AOP模塊源碼設計。算法
一、切面(Aspect)-----Spring中叫Advisor
切面由切點和加強(引介)組成,它既包括了橫切邏輯的定義,也包括了鏈接點的定義,Spring AOP就是負責實施切面的框架,它將切面所定義的橫切邏輯織入到切面所指定的鏈接點中。
二、切點(Pointcut)-----一類JoinPoint的集合
每一個程序類都擁有多個鏈接點,如一個擁有兩個方法的類,這兩個方法都是鏈接點,即鏈接點是程序類中客觀存在的事物。AOP經過「切點」定位特定的鏈接點。鏈接點至關於數據庫中的記錄,而切點至關於查詢條件。切點和鏈接點不是一對一的關係,一個切點能夠匹配多個鏈接點。在Spring中,切點經過org.springframework.aop.Pointcut接口進行描述,它使用類和方法做爲鏈接點的查詢條件,Spring AOP的規則解析引擎負責切點所設定的查詢條件,找到對應的鏈接點。其實確切地說,不能稱之爲查詢鏈接點,由於鏈接點是方法執行前、執行後等包括方位信息的具體程序執行點,而切點只定位到某個方法上,因此若是但願定位到具體鏈接點上,還須要提供方位信息。
三、加強(Advice)-----目標類方法的代理方法實現
加強是織入到目標類鏈接點上的一段程序代碼,在Spring中,加強除用於描述一段程序代碼外,還擁有另外一個和鏈接點相關的信息,這即是執行點的方位。結合執行點方位信息和切點信息,咱們就能夠找到特定的鏈接點。
四、鏈接點(Joinpoint)-----被攔截的某個目標方法
程序執行的某個特定位置:如類開始初始化前、類初始化後、類某個方法調用前、調用後、方法拋出異常後。一個類或一段程序代碼擁有一些具備邊界性質的特定點,這些點中的特定點就稱爲「鏈接點」。Spring僅支持方法的鏈接點,即僅能在方法調用前、方法調用後、方法拋出異常時以及方法調用先後這些程序執行點織入加強。鏈接點由兩個信息肯定:第一是用方法表示的程序執行點;第二是用相對點表示的方位。
五、目標對象(Target)
加強邏輯的織入目標類。若是沒有AOP,目標業務類須要本身實現全部邏輯,而在AOP的幫助下,目標業務類只實現那些非橫切邏輯的程序邏輯,而性能監視和事務管理等這些橫切邏輯則可使用AOP動態織入到特定的鏈接點上。spring
AbstractAutoProxyCreator
整個Spring AOP模塊的協做組件,它做爲AOP的指揮官角色,統一協做Advisor(切面)和AopProxy(動態代理)這兩大核心組件。它的本質是BeanPostProcessor(後置處理器)的一種實現,經過Spring IOC模塊來啓動運行。它針對的主體是Spring的Bean對象。經過掃描有@Aspect註解的類,構建候選的Advisor切面集合;在Aspect註解類中循環查找沒有@PointCut註解的方法封裝成Advice對象;經過方法上的註解找到對應的PointCut攔截目標,並把Advisor上的表達式封裝到PointCut對象中;而後結合當前的Bean對象的元數據,過濾找到有效的Advisor集合。最後經過beanClass建立針對當前bean的動態代理對象;在代理對象中,動態運行Advisor調用鏈,完成對當前bean中匹配目標的攔截和加強。數據庫
一、Advisor切面設計部分
Advisor(切面): 做爲AOP中最重要的數據結構,它是aop全部的基礎數據的歸宿,負責全部的Advice和Pointcut的封裝;
PointcutAdvisor:Advisor的擴展組件,它封裝Advisor具備的Pointcut能力;
Pointcut(切點):配置Advisor的攔截加強目標,Spring內部最終經過模糊匹配算法,最終定位到具體的攔截目標;
Advice(加強):負責Advisor切面的具體加強業務,它包含AspectJAroundAdvice、AspectJAfterAdvice、AspectJAfterThrowingAdvice、AspectJMethodBeforeAdvice、
AspectJAfterReturningAdvice等具體的加強部件。它們分別一 一對應不一樣加強類型Around、After、AfterThrowing、Before、AfterReturning 等;
MethodBeforeAdvice:註解Before加強的頂層設計,最終會統一包裝成MethodInterceptor對象,提供統一的鏈式調用能力;
MethodInterceptor:前三種加強類型的基接口,它擴展的invoke方法讓Advisor具備了基礎的攔截處理能力;
AfterReturningAdvice:註解AfterReturning加強的頂層設計,最終會統一包裝成MethodInterceptor對象,提供統一的鏈式調用能力;數據結構
二、AopProxy動態代理部分
BeanPostProcessor:全部bean後置處理器的基接口,負責定義基礎的前、後置處理行爲能力;
SmartInstantiationAwareBeanPostProcessor:繼承至BeanPostProcessor基接口,擴展了對bean的屬性、引用、類型等處理能力;
ProxyFactory:動態代理工廠接口,負責生產建立指定的AopProxy代理對象;
AopProxy:動態代理的基接口,它擴展了JDK內置的動態代理能力和Cglib類代理能力;
JdkDynamicAopProxy:對JDK內置Proxy動態代理的二次封裝;
CglibAopProxy:對cglib類動態加強的二次封裝;架構
OK, 有了上面兩大塊的基礎瞭解後,接下來咱們進入Spring AOP這塊的源碼。
AOP源碼入口
AbstractAutowireCapableBeanFactory.initializeBean()實例化bean完成後的相關後置處理
這裏是各類BeanPostProcessor後置處理器,針對當前bean作各類擴展和加強的執行入口,包括AbstractAutoProxyCreator、ServletContextAwareProcessor、BootstrapContextAwareProcessor、InitDestroyAnnotationBeanPostProcessor、InstantiationAwareBeanPostProcessorAdapter等。
冪等模式,確保一個加強面只作一次
對候選的Advisor進行過濾,篩選出做用於當前bean上的相關Advisor,並對最終的Advisor的執行順序進行排序
經過Advisor的準備,對當前bean建立動態攔截代理類
在選用代理模式的時候,spring內部採用這種方式:一、當proxyTargetClass爲true時,目標bean實現了接口或只有實現類都採用Cglib作動態代理;二、當proxyTargetClass爲false時,目標bean若實現了接口則採用JDK內置代理模式, 若目標bean只有實現類,則採用Cglib類代理模式;三、默認proxyTargetClass爲false;
AbstractAutoProxyCreator.buildAdvisors()封裝最終的各類切面對象,爲後續的鏈式調用作準備
動態代理對象生成
JDK內置代理建立
Cglib動態代理建立
核心加強業務實現
bean代理對象中,未被攔截的方法直接反射調用,執行方法
ReflectiveMethodInvocation.proceed()鏈式調用處理核心方法,全部本質AOP的實現(如:註解Transactional、Cacheable和自定義AOP攔截等),都在這裏被調用:
框架
注:本文側重點是分享Spring AOP在源碼上的實現,對於使用層面的東西不是本文的重點 ~ide
以上就是Spring AOP這塊的源碼分享,從以上的源碼咱們不看出幾點:1. AOP的本質其實就是指對一類功能加強;2.Spring實現AOP的核心思路是採用動態代理實現;3.全部相似AOP的功能最終都被封裝成MethodInterceptor接口,總體的調用鏈就是遞歸調用MethodInterceptor.invoke()方法執行相應的攔截處理;4.最後再強調一點,咱們使用AOP的最終目的是解耦業務代碼和公共的切面處理邏輯,讓整個代碼簡潔、優雅、職責分明、更易於維護和可讀。今天就到暫時這裏,更多spring源碼相關的乾貨請繼續關注!源碼分析