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代理的創建已經結束,下一節開始獲取增強器的分析。

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容