@EnableAspectJAutoProxy **2)我们看到在我们配置类上加入了@EnableAspectJAutoProxy,我们着重来分析一下这个东东给我容器中添加了什么组件?
**2.1)我们发现@EnableAspectJAutoProxy上标注了一个@Import注解,通过前面的学习我们知道@Import可以给我们容器****中添加组件
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
AspectJAutoProxyRegistrar 【#|16-Spring AOP源码分析-@EnableAspectJAutoProxy和AspectJAutoProxyRegistrar】2.2)所以我们来分析AspectJAutoProxyRegistrar类是用来干什么的?
经过跟踪源代码我们发现,AspectJAutoProxyRegistrar实现了ImportBeanDefinitionRegistrar接口,我们以前学习过
凡是实现了*ImportBeanDefinitionRegistrar可以给我们容器中添加bean定义信息*
*作用:往容器中注册了一个名称叫org.springframework.aop.config.internalAutoProxyCreator*
? *类型为AnnotationAwareAspectJAutoProxyCreator 注解的apsectj自动代理创建器*
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar { @Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {//往容器中注册对应的 aspectj注解自动代理创建器
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}}======================AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
======================
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}
//注册一个AnnotationAwareAspectJAutoProxyCreator(注解适配的切面自动创建器)
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
} private static BeanDefinition registerOrEscalateApcAsRequired(Class> cls, BeanDefinitionRegistry registry, Object source) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
//判断容器中有没有org.springframework.aop.config.internalAutoProxyCreator 名称的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;
}//容器中没有 那么就注册一个名称叫org.springframework.aop.config.internalAutoProxyCreator类型是AnnotationAwareAspectJAutoProxyCreator的bean定义
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;
}
推荐阅读
- #|15-Spring架构源码分析-Spring代理与AOP
- 微软|突发!马斯克 440 亿拿下Twitter!
- #|【Vue 路由(vue—router) 一】介绍、基本使用、嵌套路由
- #|牛客刷题——前端面试【二】谈一谈JavaScript面向对象
- #|【 探讨一下 】Vue的生命周期
- #|通过JavaScript、css、H5 实现简单的tab栏的切换和复用
- #|【vue 组件化开发 一 】组件基本使用、全局和局部组件、父组件和子组件的区别
- #|通过JavaScript 实现简单的全选、不全选的思想
- #|ES6中Array对象的方法和扩展、string的扩展方法、数组的遍历。(含例题)