『壹』 spring-AOP(二) 自動代理
下圖是AOP自動代理的流程圖
spring中已經定義了創建代理的工廠類 ProxyFactory,通過 ProxyFactory 創建代理,必須要一個被代理對象和一個增強Advisor列表
spring的動態代理實質就是對象創建完畢之後,查找篩選能夠應用於該對象上的Advisor列表,然後調用ProxyFactory創建代理對象返回。
Spring中定義了 AbstractAutoProxyCreator 類用於實現自動代理。
從繼承圖可以看出該類實現了 BeanPostProcessor 介面,覆寫了 方法。spring的bean初始化完成後會遍歷注冊的所有BeanPostProcessor實現類對象,調用其方法,該方法可以返回一個新的對象覆蓋原有對象,在此spring提供一個創建代理並覆蓋被代理對象的機會
遍歷容器中注冊的所有BeanPostProcessor,調用方法,如果返回一個新的對象會覆蓋掉原始對象注冊到spring容器中
上面分析了AbstractAutoProxyCreator是實現自動代理的關鍵,那麼在spring中如何配置一個AbstractAutoProxyCreator的實現類對象呢,spring又是如何根據配置注冊該對象的
在spring中可以通過兩種配置,啟動自動代理
這兩中方法最終都是向spring容器中注冊了一個實例,這樣在spring初始化完對象後就可以調用的方法了
上面分析了spring是在何時何處開始創建代理的,解下來分析AbstractAutoProxyCreator進行自動代理的總體實現
在方法中判斷 被代理對象不為空,調用wrapIfNecessary判斷是否對目標類進行代理
createProxy方法中通過ProxyFactory設置AOP配置,如被代理對象和Advisor列表,調用getProxy創建代理對象。
至此AbstractAutoProxyCreator完成了自動創建代理的總體實現,在該抽象類中沒有實現獲取Adviso列表r的功能,交由各個子類去實現。
分析完spring自動代理的整體實現,接下來看下AbstractAutoProxyCreator的子類是如何進行查找 Advisor、篩選Advisor、排序Advisor的。
實現了getAdvicesAndAdvisorsForBean方法,用於獲取應用於目標類的Advisor列表
在findEligibleAdvisors方法定義了查找 Advisor、篩選Advisor、排序Advisor三步操作
在spring中可以通過注冊Advisor的bean來實現對目標類的增強代理。spring會篩選出容器中所有Advisor類型的bean,用於對容器中的對象進行增強代理,查找的功能由類實現
將查找功能委託給advisorRetrievalHelper()實現,該方法的功能就是獲取Advisor類型的bean對象返回
spring除了支持配置或者手動注冊 Advisor類型的bean之外,還支持通過 @Aspect、@Before、@After等AOP註解來聲明Advisor。Advisor的查找解析由子類實現
在的findCandidateAdvisors方法中,第一步首先調父類的方法獲取到容器中注冊的所有Advisor,然後再委託aspectJAdvisorsBuilder解析註解獲取Advisor,然後合並兩個結果返回
.buildAspectJAdvisors方法解析AOP註解封裝為Advisor對象。
spring定義了一個AspectJAdvisorFactory介面用於解析AOP的註解,介面主要定義了兩個功能
AspectJAdvisorFactory的實現類提供了具體實現
調用getAdvisor方法,獲取通知方法上的Pointcut表達式,如果在方法上未解析到Pointcut,則跳過,然後根據通知方法和對應Pointcut封裝返回一個Advisor的實現類對象
解析獲取通知方法的Pointcut表達式,在該方法中會過濾掉不帶Aop註解的非通知型方法,判斷一個方法是不是通知就是判斷該方法是否聲明了切點
最終封裝返回的Advisor是類型,在該實現類的getAdvice方法會回調中的getAdvice方法,會根據通知方法上不同的註解,創建對應的Advice
回調中的getAdvice,策略創建對應的Advice實現類對象
獲取到spring容器中所有的Advisor之後,再回到類中,接下來篩選能夠應用到目標對象的Advisor。通過Advisor中的Pointcut的ClassFilter和MethodMatcher來對目標對象進行匹配。 在這個階段的篩選,只要Advisor能應用到目標類型的任意一個方法上都會返回成功
接下來看.findAdvisorsThatCanApply方法,將篩選的工作委託給AopUtils來實現
AopUtils.findAdvisorsThatCanApply方法中遍歷所有的Advisor,然後調用canApply方法判斷是否符合,在當中會區分引介增強和切點增強,引介增強是類級別的,只需要根據切點的ClassFilter對目標類進行判斷就行。
canApply方法中,通過Pointcut來進行匹配,引介增強IntroctionAdvisor直接根據其ClassFilter判斷目標類型,PointcutAdvisor根據其中的Pointcut來進行篩選
Pointcut會首先使用ClassFilter對目標類型進行過濾。如果通過,再使用 MethodMatcher 校驗 類中所有的方法,只要有一個方法匹配上,代表該Advisor符合條件。
在這里寧可多通過,也不要校驗太嚴格,因為在代理類中具體方法執行的時候,還會再一次使用Pointcut進行校驗。所以該方法中會獲取目標類型的所有介面,判斷介面中的方法,有一個符合也會返回true
當獲取到目標類型上的所有Advisor後,還需要對Advisor進行排序。Advisor的順序決定了通知方法的應用順序。
Advisor的排序主要分為兩種
接下來看下spring是怎麼實現排序的
.sortAdvisors提供了基於Ordered的排序,由spring的統一處理Ordered實現類或者添加@Ordered註解類的排序
覆寫了父類的sortAdvisors方法,在基於Ordered排序基礎上提供了同一切面下不同通知之間的排序,具體排序實現委託給了PartialOrder
至此完成Advisor的查找、篩選、排序。
『貳』 2020-07-26 帶著疑問看源碼 -- springboot aop默認採用什麼動態代理機制
了解springboot aop的動態代理方式有哪些種類?
有3種,前提均開啟spring.aop.auto=true:
1. jdk動態代理:當spring.aop.proxy-target-class=false, 引入了aspectjweaver依賴時生效
2. cglib代理:當spring.aop.proxy-target-class=true, 引入了aspectjweaver依賴時生效
3. 基礎代理:當spring.aop.proxy-target-class=true, 若沒有aspectjweaver依賴時生效,只作用於框架內部的advisors,
我們既然用springboot那麼就採用springboot的AopAutoConfiguration自動配置類來載入aop機制的,內部對@EnableAspectJAutoProxy進行了封裝,擴展了一些配置項,同時還提供了ClassProxyingConfiguration配置(下面會講到).
這個自動裝配類會是spring boot框架自動會裝配的,所以說默認aop機制是打開的,可以通過配置項:spring.aop.auto=false 手工關閉。
這個配置類會根據spring.aop.proxy-target-class配置項來決定採用jdk動態代理或者cglib動態代理:
注意:配置類生效前提是@ConditionalOnClass(Advice.class),說明只有當引入了依賴項才生效:
而這里推薦使用spring-boot-starter-aop來傳遞依賴:
這里我們已經看到提供了原生spring的兩種代理方式,接著看AopAutoConfiguration源碼發現還有個ClassProxyingConfiguration配置類,其生效條件之一是@ConditionalOnMissingClass("org.aspectj.weaver.Advice"),就是當項目里沒有aspectjweaver的依賴的時候生效。
我們進入AopConfigUtils.(registry)方法,通過幾步調用跳轉:
發現會去注冊後置處理器,查看源碼注釋:
表明了只為基礎的advisor做動態代理,而忽略應用定義的Advisors,說明項目中我們自定義的切面是不會被AOP代理的。
『叄』 Spring中的ioc和aop有什麼作用為什麼要用ioc和aop面試中多次被問到,求一個詳細 清晰的解答...
還是需要去了解,多看看書!
IOC:控制反轉,是一種設計模式。一層含義是控制權的轉移:由傳統的在程序中控制依祥橡纖賴轉移到由容器來控制;第謹仿二層是依賴注入:將相互依賴的對象分離,在spring配置文件中描述他們的依賴關系。他們的依賴關系只在使用的時候才建立。簡單來說就是不需要NEW一個對象了。
AOP:面向切面,是一種編程思想,OOP的延續。將系統中非核心的業務提取出來,進行單如汪獨處理。比如事務、日誌和安全等。這個簡單來說就是可以在一段程序之前或者之後做一些事。
Spring 的AOP和IOC都是為了解決系統代碼耦合度過高的問題。使代碼重用度高、易於維護。
不過AOP和IOC並不是spring中特有的,只是spring把他們應用的更靈活方便
『肆』 什麼是aop,aop的作用是什麼
aop是面向切面的編程。 它可以通過預編譯方式和運行期動態代理實現在不修改源代碼的情況下給程序動態統一添加功能的一種技術。 如果您學習Java的話,會在Spring中經常用到,那是你更能領悟它!
『伍』 spring aop是使用什麼代理模式
採用JAVA 動態代理設計模式設計的,目前主要應用於 事務,有了 Spring的 聲州滾明式事務可以 對程序員編碼的代碼量減少很辯碧多,冊灶余不用每層的持久化方法都自己控制事務
『陸』 aop原理。是動態代理
AOP是Aspect Oriented Programming的簡寫,中文意思是面向方面編程。
AOP的核心是方面,關注點是將共通操作提取,動態的作用的某一批目標對象上,
作用:用於改善共通邏輯和目標組件邏輯的分離,降低耦合。如Spring的聲明式事務管理就是採用AOP機制實現的。
Spring AOP採用的是動態代理技術實現,分兩種:
1,CGLIB開發包,目標組件沒有介面,AOP動態生成新的類型繼承目標組件,重寫目標組件方法來實現調用方面處理的操作,
2,實現目標組件的介面。
手打求採納啊