@EnableAspectJAutoProxy
注解源码解析
在使用@EnableAspectJAutoProxy
注解时,同时也使用@Import
注解给容器中导入了AspectJAutoProxyRegistrar
组件
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {}
AspectJAutoProxyRegistrar
组件实现了ImportBeanDefinitionRegistrar
接口,可以自定义给容器中注册组件
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) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
AspectJAutoProxyRegistrar
类里面registerBeanDefinitions
方法首先调用AopConfigUtils
类的registerAspectJAnnotationAutoProxyCreatorIfNecessary
来注册registry
,即如果需要的话就注册一个AspectJAnnotationAutoProxyCreator
组件。
AopConfigUtils
类的registerAspectJAnnotationAutoProxyCreatorIfNecessary
方法中又继续调用重载方法registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null)
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
重载方法registerAspectJAnnotationAutoProxyCreatorIfNecessary
方法又进一步调用registerOrEscalateApcAsRequired
方法,并且在registerOrEscalateApcAsRequired()
方法中,传入了AnnotationAwareAspectJAutoProxyCreator.class
对象
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
在registerOrEscalateApcAsRequired()
方法中会做一个判断,即首先判断registry
(也就是IOC容器)是否包含名称为org.springframework.aop.config.internalAutoProxyCreator
的bean。如果包含,将名称为org.springframework.aop.config.internalAutoProxyCreator
的bean从容器中取出,并且判断cls
对象的name
值和apcDefinition
的beanClassName
值是否相等,若不相等,则获取apcDefinition
和cls
它俩的优先级,如果apcDefinition
的优先级小于cls
的优先级,那么将apcDefinition
的beanClassName
设置为cls
的name
值。如果不包含,会使用RootBeanDefinition
来创建一个bean的定义信息(即beanDefinition
),并且将org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
的Class
对象作为参数传递进来。最终在AopConfigUtils
类的registerOrEscalateApcAsRequired()
方法中,会通过registry
调用registerBeanDefinition()
方法注册组件,注册的组件的类型是org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator
,组件的名字是org.springframework.aop.config.internalAutoProxyCreator
。
private static BeanDefinition registerOrEscalateApcAsRequired(Class<?> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
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);
registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
return beanDefinition;
}
之后,通过AnnotationConfigUtils
类的attributesFor()
方法来获取@EnableAspectJAutoProxy
注解的信息。接着,就是判断proxyTargetClass
属性的值是否为true
,若为true
则调用AopConfigUtils
类的forceAutoProxyCreatorToUseClassProxying()
方法;继续判断exposeProxy
属性的值是否为true
,若为true
则调用AopConfigUtils
类的forceAutoProxyCreatorToExposeProxy()
方法
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
简而言之,Spring的配置类上添加@EnableAspectJAutoProxy
注解之后,会向IOC容器中注册AnnotationAwareAspectJAutoProxyCreator
组件,即注解装配模式的AspectJ切面自动代理创建器。
AnnotationAwareAspectJAutoProxyCreator
类的结构图:
AnnotationAwareAspectJAutoProxyCreator
类实现了Aware
与BeanPostProcessor
接口,这两个接口都和bean的初始化有关,由此可以推测此AnnotationAwareAspectJAutoProxyCreator
类的主要处理方法都来自于这两个接口中的实现方法。