乐趣区

Spring源码分析系列一通过EnableAspectJAutoProxy分析AOP加载过程

Spring 源码分析系列(一)– 通过 @EnableAspectJAutoProxy 分析 AOP 加载过程

  AOP 是面向切面编程,是相对于 OOP 面向对象编程而言的。Spring 的 AOP 的存在的目的是为了解耦。AOP 可以让一组类共享相同的行为。在 OOP 中只能通过继承类和实现接口来实现,但是这样的缺点是会使代码的耦合度增加,且类继承只能为单继承,阻碍更多行为添加到一组类上,AOP 的出现弥补了 OOP 的不足。

  使用 @EnableAspectJAutoProxy 注解开启 Spring 对 AspectJ 的支持。
  添加 @EnableAspectJAutoProxy 注解,表示开启 AOP 代理自动配置,如果使用 @EnableAspectJAutoProxy 注解,表示使用 cglib 进行代理对象的生成。设置 @EnableAspectJAutoProxy(exposeProxy=true) 表示通过 AOP 框架暴露该代理对象,aopContext 能够访问。

  下面看一下 @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 方法主要实现了两个功能:

  • 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;
}
退出移动版