Spring中這麼重要的AnnotationAwareAspectJAutoProxyCreator類是幹嘛的?

冰河團隊發表於2021-07-11

大家好,我是冰河~~

停更了很久的【Spring註解系列】專題,終於重新更新了,我們還是接著之前的文章繼續往下更新。在《【Spring註解驅動開發】二狗子讓我給他講講@EnableAspectJAutoProxy註解》一文中,我們通過檢視@EnableAspectJAutoProxy 註解的原始碼,如下所示。

package org.springframework.context.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
 boolean proxyTargetClass() default false;
 boolean exposeProxy() default false;
}

得知,@EnableAspectJAutoProxy 註解是通過使用@Import(AspectJAutoProxyRegistrar.class) 給容器中註冊一個名字叫做internalAutoProxyCreator = AnnotationAwareAspectJAutoProxyCreator的元件。

並且我們也分析了AnnotationAwareAspectJAutoProxyCreato類的核心繼承關係,如下所示。

  AnnotationAwareAspectJAutoProxyCreator
       --AspectJAwareAdvisorAutoProxyCreator
         --AbstractAdvisorAutoProxyCreator
           --AbstractAutoProxyCreator
             -- ProxyProcessorSupport, SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

檢視繼承關係可以發現,此類實現了AwareBeanPostProcessor介面,這兩個介面都和Spring bean的初始化有關,由此推測此類主要處理方法都來自這兩個介面的實現方法。同時該類也實現了order方法。

那今天,我們就來看看AnnotationAwareAspectJAutoProxyCreator 類的呼叫流程,具體來說,就是看看 ``AnnotationAwareAspectJAutoProxyCreator` 作為BeanPostProcessor做了哪些工作,作為BeanFactoryAware做了哪些工作。

分析AbstractAutoProxyCreator類

AnnotationAwareAspectJAutoProxyCreator類的繼承關係上可以看出, 是在AbstractAutoProxyCreator類開始實現 SmartInstantiationAwareBeanPostProcessor介面和 BeanFactoryAware 介面的。

所以,我們先來看看 AbstractAutoProxyCreator 類進行分析。

AbstractAutoProxyCreator 類的定義我們可以看出,AbstractAutoProxyCreator類直接實現了SmartInstantiationAwareBeanPostProcessor 介面和 BeanFactoryAware 介面。

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
		implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

既然 AbstractAutoProxyCreator 實現了 BeanFactoryAware 介面, 那麼 AbstractAutoProxyCreator 類中就一定存在setBeanFactory()方法,如下所示。

@Override
public void setBeanFactory(BeanFactory beanFactory) {
    this.beanFactory = beanFactory;
}

@Nullable
protected BeanFactory getBeanFactory() {
    return this.beanFactory;
}

果然,我們在 AbstractAutoProxyCreator 類中找到了setBeanFactory()方法和getBeanFactory()方法。

另外,在 AbstractAutoProxyCreator 類中還存在與BeanPostProcessor後置處理器有關的方法,分別為:postProcessBeforeInstantiation()、postProcessAfterInstantiation()、postProcessProperties()、postProcessBeforeInitialization()、postProcessAfterInitialization()。整體原始碼如下所示。

@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    Object cacheKey = getCacheKey(beanClass, beanName);
    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)){
        if (this.advisedBeans.containsKey(cacheKey)) {
            return null;
        }
        if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }
    TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
    if (targetSource != null) {
        if (StringUtils.hasLength(beanName)) {
            this.targetSourcedBeans.add(beanName);
        }
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
        Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }
    return null;
}

@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) {
    return true;
}

@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
    return pvs;
}

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
    return bean;
}

@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

也就是說,在AbstractAutoProxyCreator 類中,存在後置處理器的邏輯。

到這,我們就在AbstractAutoProxyCreator 類中看到了BeanFactoryAware 的實現和後置處理器的實現。

接下來,我們再來看看AbstractAutoProxyCreator 的子類 AbstractAdvisorAutoProxyCreator類。

分析AbstractAdvisorAutoProxyCreator類

AbstractAdvisorAutoProxyCreator類中,我們會看到如下程式碼。

@Override
public void setBeanFactory(BeanFactory beanFactory) {
    super.setBeanFactory(beanFactory);
    if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
        throw new IllegalArgumentException(
            "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
    }
    initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}

說明在AbstractAdvisorAutoProxyCreator類中重寫了setBeanFactory()方法。並且在AbstractAdvisorAutoProxyCreator類的setBeanFactory()方法中,首先會呼叫AbstractAutoProxyCreator 類中的setBeanFactory()方法。

在setBeanFactory()方法中會呼叫initBeanFactory()方法,initBeanFactory()方法的實現如下所示。

protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}

initBeanFactory()方法的實現比較簡單,這裡,我就不多說了。

另外,我們並沒有在AbstractAdvisorAutoProxyCreator類中找到與後置處理器相關的方法。

接下來,我們繼續分析AbstractAdvisorAutoProxyCreator類的子類AspectJAwareAdvisorAutoProxyCreator類。

分析AspectJAwareAdvisorAutoProxyCreator類

通過檢視AspectJAwareAdvisorAutoProxyCreator類的原始碼,我們得知,在 AspectJAwareAdvisorAutoProxyCreator類中沒有與後置處理器相關的程式碼。所以,我們繼續向上分析 AspectJAwareAdvisorAutoProxyCreator類的子類 AnnotationAwareAspectJAutoProxyCreator

分析AnnotationAwareAspectJAutoProxyCreator類

AnnotationAwareAspectJAutoProxyCreator類中,我們可以找到一個initBeanFactory()方法,如下所示。

@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    super.initBeanFactory(beanFactory);
    if (this.aspectJAdvisorFactory == null) {
        this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
    }
    this.aspectJAdvisorsBuilder =
        new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}

看到這裡,小夥伴們對於setBeanFactory的呼叫流程有點清晰了吧?其實setBeanFactory()的呼叫流程為:首先會執行 AbstractAdvisorAutoProxyCreator類中的setBeanFactory()方法,在AbstractAdvisorAutoProxyCreator類中的setBeanFactory()方法中會呼叫其父類AbstractAutoProxyCreator 中的setBeanFactory()方法,然後在AbstractAdvisorAutoProxyCreator類中的setBeanFactory()方法中呼叫initBeanFactory()方法。由於在子類AnnotationAwareAspectJAutoProxyCreator中重寫了initBeanFactory()方法,最終呼叫的就是AnnotationAwareAspectJAutoProxyCreator類中的initBeanFactory()方法。這麼說有點繞,我們來看一張圖吧。

注意,上圖中的AbstractAdvisorAutoProxyCreator類中的setBeanFactory()方法作為程式呼叫的入口,它會依次呼叫AbstractAutoProxyCreator#setBeanFactory()AnnotationAwareAspectJAutoProxyCreator#initBeanFactory() ,然後,再由 AnnotationAwareAspectJAutoProxyCreator#initBeanFactory() 呼叫 AbstractAdvisorAutoProxyCreator#initBeanFactory()

除此之外,我們在AnnotationAwareAspectJAutoProxyCreator類中,並沒有發現與後置處理器相關的程式碼了。

好了,以上就是我們分析的有關AnnotationAwareAspectJAutoProxyCreator類的原始碼。在下一篇文章中,我們開始debug除錯這些原始碼的具體執行流程。

好了,今天就到這兒吧,我是冰河,我們下期見~

相關文章