Spring原始碼-AOP(六)-AOP代理的建立
前言
上一篇寫了AspectJAutoProxyBeanDefinitionParser的註冊,以及相關AOP屬性的註冊,接下來看下AspectJAutoProxyBeanDefinitionParser的自動註冊以及它的層級結構。
從圖中可以看到AnnotationAwareAspectJAutoProxyCreator實現了BeanPostProcessor,在之前的IOC章節我們之前描述過,Spring載入該bean後會在例項化前呼叫postProcessAfterInitialization()方法,而我們對於AOP邏輯的分析也由此開始。
AOP邏輯分析
【AbstractAutoProxyCreator】
talk is cheap, show you the code:
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
if (bean != null) {
//根據給定的class和name構建出key,格式:beanClassName_beanName
Object cacheKey = getCacheKey(bean.getClass(), beanName);
if (!this.earlyProxyReferences.contains(cacheKey)) {
//如果他適合被代理,則需要封裝指定bean
return wrapIfNecessary(bean, beanName, cacheKey);
}
}
return bean;
}
protected Object wrapIfNecessary(Object bean, @Nullable String beanName, Object cacheKey) {
//如果已經處理過就直接返回
if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
//不需要增強
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//給定的bean類是否代表一個基礎設施類,基礎設施類不應代理,活配置了指定bean不需要自動代理
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// Create proxy if we have advice.
//如果存在增強方法則建立代理
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//如果獲取了增強則需要針對增強建立代理
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//建立代理
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
在以上函式中我們已經看到了代理建立的雛形。當然和別的醫院,在開始前先進行一系列的判斷,比如是否已經處理過或者是否需要挑錯,而真正建立代理的程式碼是從getAdvicesAndAdvisorsForBean()開始的。
建立代理前主要包括兩個步驟,如下:
- 1、獲取增強方法或者增強器
- 2、根據獲取的增強進行代理
核心邏輯時序圖如下:
AbstractAutoProxyCreator的postProcessAfterInitialization() 方法執行時序圖
雖然看似很簡單,但是每個步驟中都進行了大量的複雜邏輯處理。
AOP設計基礎
這裡再回顧下Spring-AOP的設計基礎
-
增強(Advice):Advice(也翻作 通知)定義了連線點做什麼,為切面增強提供了織入的介面。在 Spring AOP 中,它主要描述 Spring AOP 圍繞方法呼叫而注入的切面行為。Advice 是 AOP 聯盟定義的一個介面,具體的介面定義在 org.aopalliance.aop.Advice 中。在 Spring AOP 的實現中,使用了這個統一介面,並通過這個介面,為 AOP 切面增強的注入功能做了更多的細化和擴充套件,比如前面提到的具體通知型別,如BeforeAdvice、AfterAdvice、ThrowsAdvice等
-
切點:Pointcut(關注點,也稱 切點)用於決定 Advice 增強作用於哪個連線點,也就是說通過 Pointcut 來定義需要增強的方法集合,而這些集合的選取可以通過一定的規則來完成,例如:這些需要增強的地方可以由某個正規表示式來進行標識,或根據某個方法名來進行匹配等。
-
通知器:Advisor(通知器)用一個物件將對目標方法的切面增強設計(Advice)和關注點的設計(Pointcut)結合起來
結束
相應的AOP代理的建立已經結束,下一節開始獲取增強器的分析。
相關文章
- AOP原始碼解析之二-建立AOP代理前傳,獲取AOP資訊原始碼
- AOP詳解之三-建立AOP代理後記,建立AOP代理
- Spring AOP 自動建立代理Spring
- 死磕Spring之AOP篇 - Spring AOP自動代理(三)建立代理物件Spring物件
- Spring框架系列(10) - Spring AOP實現原理詳解之AOP代理的建立Spring框架
- Spring AOP 原始碼解析Spring原始碼
- spring原始碼解讀-aopSpring原始碼
- Spring AOP之原始碼分析Spring原始碼
- 【Spring原始碼分析】AOP原始碼解析(上篇)Spring原始碼
- 【Spring原始碼分析】AOP原始碼解析(下篇)Spring原始碼
- 【Spring AOP】AOP 底層實現原理 —— 動態代理類的建立(JDK、CGlib)、工廠如何加工原始物件SpringJDKCGLib物件
- Spring AOP 原理原始碼深度剖析Spring原始碼
- Spring原理與原始碼分析系列(六)- Spring AOP入門與概述Spring原始碼
- Spring原始碼剖析6:Spring AOP概述Spring原始碼
- Spring AOP代理執行解析Spring
- 死磕Spring之AOP篇 - Spring AOP自動代理(一)入口Spring
- Spring中AOP相關原始碼解析Spring原始碼
- 5.1 Spring5原始碼--Spring AOP原始碼分析一Spring原始碼
- 5.2 Spring5原始碼--Spring AOP原始碼分析二Spring原始碼
- guava eventbus不支援spring的aop代理GuavaSpring
- 3種代理模式-理解Spring Aop模式Spring
- Spring AOP --JDK動態代理方式SpringJDK
- 從代理機制到Spring AOPSpring
- 原始碼解析Spring AOP的載入與生效原始碼Spring
- 《四 spring原始碼》利用TransactionManager手寫spring的aopSpring原始碼
- 死磕Spring之AOP篇 - Spring AOP兩種代理物件的攔截處理Spring物件
- Spring review--動態代理和AOP程式碼的演化SpringView
- 深入理解Spring AOP的動態代理Spring
- 5.2 spring5原始碼--spring AOP原始碼分析三---切面原始碼分析Spring原始碼
- 從動態代理到Spring AOP(上)Spring
- 從動態代理到Spring AOP(中)Spring
- Spring中AOP相關的API及原始碼解析SpringAPI原始碼
- 按照自己的思路研究Spring AOP原始碼【2】Spring原始碼
- Spring 的 AOPSpring
- Spring的AOPSpring
- 死磕Spring之AOP篇 - Spring AOP自動代理(二)篩選合適的通知器Spring
- Spring AOP高階應用與原始碼剖析Spring原始碼
- Spring原始碼分析之AOP從解析到呼叫Spring原始碼