15、AOP之@EnableAspectJAutoProxy原理分析

与世无争的帅哥 提交于 2020-02-27 12:45:47

1.1、@EnableAspectJAutoProxy的执行时机

@Target(ElementType.TYPE)  
@Retention(RetentionPolicy.RUNTIME)  
@Documented  
@Import(AspectJAutoProxyRegistrar.class)  
public @interface EnableAspectJAutoProxy {  
     boolean proxyTargetClass() default false;  
	 
     boolean exposeProxy() default false;  
}
发现EnableAspectJAutoProxy它就是给容器中注册了一个AspectJAutoProxyRegistrar,而AspectJAutoProxyRegistrar它实现了
ImportBeanDefinitionRegistrar接口,会向会编程式的向IOC容器中注册组件.
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {  
    
     // 下面先分析下这个方法何时被调用
     public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {  
         AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);  
         AnnotationAttributes enableAspectJAutoProxy =  
                            AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);  
         if (enableAspectJAutoProxy != null) {  
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {  
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);  
            }  
            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {  
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);  
            }  
         }  
     }  
}
// 首先要在主配置类上开启
@SpringBootApplication
@EnableAspectJAutoProxy  
public class SpringbootApplication {
// Invoke factory processors registered as beans in the context.  
// 在SpringBoot容器刷新过程中,会调用容器中的BeanFactoryPostProcessors的方法,其中有一个是ConfigurationClassPostProcessor,
// 这个在第八篇配置类中也讲过,它是BeanDefinitionRegistryPostProcessor类型的,在这里时会调用
// 其postProcessBeanDefinitionRegistry方法
invokeBeanFactoryPostProcessors(beanFactory);
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
// 调用其postProcessBeanDefinitionRegistry方法会走到这里,下面这个方法只保留了关键步骤,这里第八篇中也分析过了
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
    // 1) 解析配置类
    parser.parse(candidates);
    // 2) 加载BeanDefinition
    this.reader.loadBeanDefinitions(configClasses);
}
// 步骤1会走到这里
// sourceClass在这里分析的是主配置类,是,调用getImports(sourceClass)是递归扫描该类上面的所有注解,会一层一层进去扫描
// 获取@Import中导入的类
processImports(configClass, sourceClass, getImports(sourceClass), true);
// 那么就会获取到这个AspectJAutoProxyRegistrar,下面分析的candidate就是AspectJAutoProxyRegistrar
@Import(AspectJAutoProxyRegistrar.class)  
public @interface EnableAspectJAutoProxy {
// processImports方法会走到这里
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {  
    // Candidate class is an ImportBeanDefinitionRegistrar ->  
    // delegate to it to register additional bean definitions  Class<?> candidateClass = candidate.loadClass();  
    ImportBeanDefinitionRegistrar registrar =  
                               BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);  
    ParserStrategyUtils.invokeAwareMethods(registrar, this.environment, this.resourceLoader, this.registry);  
	// 实例化一下并放到一个map中记录,后面在步骤2中会用到
    configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());  
}

public void addImportBeanDefinitionRegistrar(ImportBeanDefinitionRegistrar registrar, 
                                                                  AnnotationMetadata importingClassMetadata) {  
    this.importBeanDefinitionRegistrars.put(registrar, importingClassMetadata);  
}
// 下面来看步骤2,步骤2会走到这里
// this.reader.loadBeanDefinitions(configClasses)
// configClass.getImportBeanDefinitionRegistrars()获取的就是刚刚放入map中的
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());

private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {  
    // 依此遍历每个registrar,调用其registerBeanDefinitions方法
    registrars.forEach((registrar, metadata) -> registrar.registerBeanDefinitions(metadata, this.registry));  
}

1.2、注册AnnotationAwareAspectJAutoProxyCreator

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {  
     // 通过上面的分析,我们走到了这里
     public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {  
	 // 下面看这一步骤
         AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);  
		 
         // 这一步骤就是设置一些属性,我们没有配置,默认就不会设置
	 AnnotationAttributes enableAspectJAutoProxy =  
                            AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);  
         if (enableAspectJAutoProxy != null) {  
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {  
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);  
            }  
            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {  
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);  
            }  
         }  
     }  
}
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);  

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(  
                                                    BeanDefinitionRegistry registry, @Nullable Object source) {  
    // 就是向容器中注入AnnotationAwareAspectJAutoProxyCreator
    return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);  
}

private static BeanDefinition registerOrEscalateApcAsRequired(  
                                      Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {  
    // 走到这里,容器中默认是没有的
    // String AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";
    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);  
    // 往容器中注册这样一个bean,它是AnnotationAwareAspectJAutoProxyCreator类型的,名字如下,后面会用到
    // AUTO_PROXY_CREATOR_BEAN_NAME = "org.springframework.aop.config.internalAutoProxyCreator";
    registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);  
    return beanDefinition;  
}

1.3、AnnotationAwareAspectJAutoProxyCreator的作用时机

查看继承关系,发现AnnotationAwareAspectJAutoProxyCreator它是SmartInstantiationAwareBeanPostProcessor,
也就是BeanPostProcessor. 它用于组件的创建前后做后置处理,恰好AOP的核心是用代理对象代替普通对象,用这种后置处理器刚
好能完成需求. 我们下面来看下AnnotationAwareAspectJAutoProxyCreator它是何时被实例化的
// Invoke factory processors registered as beans in the context.  
// 这里就是本文一开始分析的步骤,这步骤完成之后,容器的BeanDefinition已经被扫描注册到了容器中,但还没有创建实例对象
invokeBeanFactoryPostProcessors(beanFactory);  
  
// Register bean processors that intercept bean creation.  
registerBeanPostProcessors(beanFactory);
// 上面代码会走到
registerBeanPostProcessors(beanFactory, orderedPostProcessors)

private static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, 
                                               List<BeanPostProcessor> postProcessors) {  
    for (BeanPostProcessor postProcessor : postProcessors) {  
        beanFactory.addBeanPostProcessor(postProcessor);  
    }  
}

@Override  
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {  
    // Remove from old position, if any  
    this.beanPostProcessors.remove(beanPostProcessor);  
    // Track whether it is instantiation/destruction aware  
    if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {  
	// 我们上面说的AnnotationAwareAspectJAutoProxyCreator,是SmartInstantiationAwareBeanPostProcessor,
	// 而InstantiationAwareBeanPostProcessor它是InstantiationAwareBeanPostProcessor类型的
	// 所以下面这个字段会被设置为true
        this.hasInstantiationAwareBeanPostProcessors = true;  
    }  
    if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {  
        this.hasDestructionAwareBeanPostProcessors = true;  
    }  
    // Add to end of list  
    // 若原来有,先删掉,再添加进去
    this.beanPostProcessors.add(beanPostProcessor);  
}
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!