Spring源碼分析系列(一)--經過@EnableAspectJAutoProxy分析AOP加載過程

Spring源碼分析系列(一)--經過@EnableAspectJAutoProxy分析AOP加載過程

  AOP是面向切面編程,是相對於OOP面向對象編程而言的。Spring的AOP的存在的目的是爲了解耦。AOP可讓一組類共享相同的行爲。在OOP中只能經過繼承類和實現接口來實現,可是這樣的缺點是會使代碼的耦合度增長,且類繼承只能爲單繼承,阻礙更多行爲添加到一組類上,AOP的出現彌補了OOP的不足。java

  使用@EnableAspectJAutoProxy註解開啓Spring對AspectJ的支持。
  添加@EnableAspectJAutoProxy註解,表示開啓AOP代理自動配置,若是使用@EnableAspectJAutoProxy註解,表示使用cglib進行代理對象的生成。設置@EnableAspectJAutoProxy(exposeProxy=true)表示經過AOP框架暴露該代理對象,aopContext可以訪問。spring

  下面看一下@EnableAspectJAutoProxy這個類的源碼編程

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

    /**
     * Indicate whether subclass-based (CGLIB) proxies are to be created as opposed
     * to standard Java interface-based proxies. The default is {@code false}.
     */
    // true--使用CGLIB基於類建立代理,false--使用java接口建立代理
    boolean proxyTargetClass() default false;

    /**
     * Indicate that the proxy should be exposed by the AOP framework as a {@code ThreadLocal}
     * for retrieval via the {@link org.springframework.aop.framework.AopContext} class.
     * Off by default, i.e. no guarantees that {@code AopContext} access will work.
     * @since 4.3.1
     */
    // 是否經過aop礦建暴露該代理對象,aopContext可以訪問
    boolean exposeProxy() default false;

}

  經過上面的代碼能夠看出@EnableAspectJAutoProxy把AspectJAutoProxyRegistrar.class對象導入到了容器中。利用AspectJAutoProxyRegistrar給容器中註冊了一個AnnotationAwareAspectJAutoProxyCreator。框架

AspectJAutoProxyRegistrar

AspectJAutoProxyRegistrar類中的registerBeanDefinitions方法主要實現了兩個功能:ide

  • 1.註冊AnnotationAwareAspectJAutoProxyCreator
  • 2.獲取@EnableAspectJAutoProxy註解的屬性信息
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    /**
     * Register, escalate, and configure the AspectJ auto proxy creator based on the value
     * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
     * {@code @Configuration} class.
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        //註冊AnnotationAwareAspectJAutoProxyCreator
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
        //獲取@EnableAspectJAutoProxy註解的屬性信息
        AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata,EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy != null) {
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
    }
}

1.註冊AnnotationAwareAspectJAutoProxyCreator

@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}

//註冊AnnotationAwareAspectJAutoProxyCreator
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
        BeanDefinitionRegistry registry, @Nullable Object source) {
    return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

@Nullable
private static BeanDefinition registerOrEscalateApcAsRequired(
        Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    //判斷是否包含目標bean
    if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
        BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
        if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
            int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
            int requiredPriority = findPriorityForClass(cls);
            if (currentPriority < requiredPriority) {
                apcDefinition.setBeanClassName(cls.getName());
            }
        }
        return null;
    }

    RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
    beanDefinition.setSource(source);
    beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
    beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    //將beanDefinition註冊到registry中,name爲AUTO_PROXY_CREATOR_BEAN_NAME
    //AUTO_PROXY_CREATOR_BEAN_NAME = org.springframework.aop.config.internalAutoProxyCreator
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
    return beanDefinition;
}
相關文章
相關標籤/搜索