Spring 注解配置加载流程源码解析(二)

本文详细解析了Spring框架中ConfigurationClassPostProcessor的注解配置加载流程,包括它如何处理@Configuration、@Component等注解,以及BeanDefinition的注册、解析和验证过程。通过跟踪processConfigBeanDefinitions方法,了解了从BeanDefinition的获取、检查到配置类的递归解析,再到@Import、@ComponentScan等注解的处理,最后完成BeanDefinition的注册。深入理解这一流程对于掌握Spring自动装配原理至关重要。
摘要由CSDN通过智能技术生成

ConfigurationClassPostProcessor 注解解析流程

  1. Configuration是对哪些注解进行解析的?
    1)@Component
    2)@PropertySource
    3)@ComponentScan、@ComponentScans
    4)@import
    5)@importResource
    6)@Bean
  2. ConfigurationClassPostProcessor是怎样被调用的?
    1)我们先来看BeanFactoryPostProcessor 的执行,扫描所有的BeanDefinitionRegistryPostProcessor类型的BeanDefinition,查找到一个名为org.springframework.context.annotation.internalConfigurationAnnotationProcessor 的 BeanDefinition
    但是这个名字对应的BeanDefinition到底是那个呢?
    在下面的代码我们可以看到,在创建AnnotationConfigApplicationContext时候,构造方法中new了一个 AnnotatedBeanDefiniitonReader对象,里面调用了AnnotationConfigUtils方法,往BeanFactory中注册了一系列的内置BeanFactoryPostProcessor和BeanPostProcessor。
    org.springframework.context.annotation.internalConfigurationAnnotationProcessor对应的类就是ConfigurationClassPostProcessor
    在这里插入图片描述
    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
   
        Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
        Assert.notNull(environment, "Environment must not be null");
        this.registry = registry;
        this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }
public abstract class AnnotationConfigUtils {
   
/**
     * The bean name of the internally managed Configuration annotation processor.
     */
    public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME =
            "org.springframework.context.annotation.internalConfigurationAnnotationProcessor";

    /**
     * The bean name of the internally managed BeanNameGenerator for use when processing
     * {@link Configuration} classes. Set by {@link AnnotationConfigApplicationContext}
     * and {@code AnnotationConfigWebApplicationContext} during bootstrap in order to make
     * any custom name generation strategy available to the underlying
     * {@link ConfigurationClassPostProcessor}.
     * @since 3.1.1
     */
    public static final String CONFIGURATION_BEAN_NAME_GENERATOR =
            "org.springframework.context.annotation.internalConfigurationBeanNameGenerator";

    /**
     * The bean name of the internally managed Autowired annotation processor.
     */
    public static final String AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
            "org.springframework.context.annotation.internalAutowiredAnnotationProcessor";

    /**
     * The bean name of the internally managed Required annotation processor.
     * @deprecated as of 5.1, since no Required processor is registered by default anymore
     */
    @Deprecated
    public static final String REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME =
            "org.springframework.context.annotation.internalRequiredAnnotationProcessor";

    /**
     * The bean name of the internally managed JSR-250 annotation processor.
     */
    public static final String COMMON_ANNOTATION_PROCESSOR_BEAN_NAME =
            "org.springframework.context.annotation.internalCommonAnnotationProcessor";

    /**
     * The bean name of the internally managed JPA annotation processor.
     */
    public static final String PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME =
            "org.springframework.context.annotation.internalPersistenceAnnotationProcessor";

    private static final String PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME =
            "org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor";

    /**
     * The bean name of the internally managed @EventListener annotation processor.
     */
    public static final String EVENT_LISTENER_PROCESSOR_BEAN_NAME =
            "org.springframework.context.event.internalEventListenerProcessor";

    /**
     * The bean name of the internally managed EventListenerFactory.
     */
    public static final String EVENT_LISTENER_FACTORY_BEAN_NAME =
            "org.springframework.context.event.internalEventListenerFactory";

    private static final boolean jsr250Present;

    private static final boolean jpaPresent;

    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
            BeanDefinitionRegistry registry, @Nullable Object source) {
   

        // 获取beanFactory
        DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
        if (beanFactory != null) {
   
            if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
   
                // //设置依赖比较器
                beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
            }
            if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
   
                // //设置自动装配解析器
                beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
            }
        }

        // 创建BeanDefinitionHolder集合
        Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

        // 注册内部管理的用于处理@configuration注解的后置处理器的bean
        if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
   
            RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
            def.setSource(source);
            // 注册BeanDefinition到注册表中
            beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // 注册内部管理的用于处理@Autowired,@Value,@Inject以及@Lookup注解的后置处理器bean
        if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
   
            RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
        // 注册内部管理的用于处理JSR-250注解,例如@Resource,@PostConstruct,@PreDestroy的后置处理器bean
        if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
   
            RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
        // 注册内部管理的用于处理JPA注解的后置处理器bean
        if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
   
            RootBeanDefinition def = new RootBeanDefinition();
            try {
   
                def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                        AnnotationConfigUtils.class.getClassLoader()));
            }
            catch (ClassNotFoundException ex) {
   
                throw new IllegalStateException(
                        "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
            }
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
        }

        // 注册内部管理的用于处理@EventListener注解的后置处理器的bean
        if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
   
            RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
        }

        // 注册内部管理用于生产ApplicationListener对象的EventListenerFactory对象
        if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
   
            RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
            def.setSource(source);
            beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
        }

        return beanDefs;
    }
}
    private static void invokeBeanDefinitionRegistryPostProcessors(
            Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
   

        for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
   
            postProcessor.postProcessBeanDefinitionRegistry(registry);
        }
    }
  1. ConfigurationClassPostProcessor怎样进行注解解析的?
    1)processConfigBeanDefinitions方法
    public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
    PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
    // 根据对应的registry对象生成hashcode值,此对象只会操作一次,如果之前处理过则抛出异常
    int registryId = System.identityHashCode(registry);
    if (this.registriesPostProcessed.contains(registryId)) {
    throw new IllegalStateException(
    "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
    }
    if (this.factoriesPostProcessed.contains(registryId)) {
    throw new IllegalStateException(
    "postProcessBeanFactory already called on this post-processor against " + registry);
    }
    // 将马上要进行处理的registry对象的id值放到已经处理的集合对象中
    this.registriesPostProcessed.add(registryId);

    // 处理配置类的bean定义信息
    processConfigBeanDefinitions(registry);
    

    }
    /**

    • 构建和验证一个类是否被@Configuration修饰,并做相关的解析工作

    • 如果你对此方法了解清楚了,那么springboot的自动装配原理就清楚了

    • Build and validate a configuration model based on the registry of

    • {@link Configuration} classes.
      */
      public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
      // 创建存放BeanDefinitionHolder的对象集合
      List configCandidates = new ArrayList<>();
      // 当前registry就是DefaultListableBeanFactory,获取所有已经注册的BeanDefinition的beanName
      String[] candidateNames = registry.getBeanDefinitionNames();

      // 遍历所有要处理的beanDefinition的名称,筛选对应的beanDefinition(被注解修饰的)
      for (String beanName : candidateNames) {
      // 获取指定名称的BeanDefinition对象
      BeanDefinition beanDef = registry.getBeanDefinition(beanName);
      // 如果beanDefinition中的configurationClass属性不等于空,那么意味着已经处理过,输出日志信息
      if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
      if (logger.isDebugEnabled()) {
      logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
      }
      }
      // 判断当前BeanDefinition是否是一个配置类,并为BeanDefinition设置属性为lite或者full,此处设置属性值是为了后续进行调用
      // 如果Configuration配置proxyBeanMethods代理为true则为full
      // 如果加了@Bean、@Component、@ComponentScan、@Import、@ImportResource注解,则设置为lite
      // 如果配置类上被@Order注解标注,则设置BeanDefinition的order属性值
      else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
      // 添加到对应的集合对象中
      configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
      }
      }

      // Return immediately if no @Configuration classes were found
      // 如果没有发现任何配置类,则直接返回
      if (configCandidates.isEmpty()) {
      return;
      }

      // Sort by previously determined @Order value, if applicable
      // 如果适用,则按照先前确定的@Order的值排序
      configCandidates.sort((bd1, bd2) -> {
      int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
      int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
      return Integer.compare(i1, i2);
      });

      // Detect any custom bean name generation strategy supplied through the enclosing application context
      // 判断当前类型是否是SingletonBeanRegistry类型
      SingletonBeanRegistry sbr = null;
      if (registry instanceof SingletonBeanRegistry) {
      // 类型的强制转换
      sbr = (SingletonBeanRegistry) registry;
      // 判断是否有自定义的beanName生成器
      if (!this.localBeanNameGeneratorSet) {
      // 获取自定义的beanName生成器
      BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
      AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
      // 如果有自定义的命名生成策略
      if (generator != null) {
      //设置组件扫描的beanName生成策略
      this.componentScanBeanNameGenerator = generator;
      // 设置import bean name生成策略
      this.importBeanNameGenerator = generator;
      }
      }
      }

      // 如果环境对象等于空,那么就重新创建新的环境对象
      if (this.environment == null) {
      this.environment = new StandardEnvironment();
      }

      // Parse each @Configuration class
      // 实例化ConfigurationClassParser类,并初始化相关的参数,完成配置类的解析工作
      ConfigurationClassParser parser = new ConfigurationClassParser(
      this.metadataReaderFactory, this.problemReporter, this.environment,
      this.resourceLoader, this.componentScanBeanNameGenerator, registry);

      // 创建两个集合对象,
      // 存放相关的BeanDefinitionHolder对象
      Set candidates = new LinkedHashSet<>(configCandidates);
      // 存放扫描包下的所有bean
      Set alreadyParsed = new HashSet<>(configCandidates.size());
      do {
      // 解析带有@Controller、@Import、@ImportResource、@ComponentScan、@ComponentScans、@Bean的BeanDefinition
      parser.parse(candidates);
      // 将解析完的Configuration配置类进行校验,1、配置类不能是final,2、@Bean修饰的方法必须可以重写以支持CGLIB
      parser.validate();

       // 获取所有的bean,包括扫描的bean对象,@Import导入的bean对象
       Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
       // 清除掉已经解析处理过的配置类
       configClasses.removeAll(alreadyParsed);
      
       // Read the model and create bean definitions based on its content
       // 判断读取器是否为空,如果为空的话,就创建完全填充好的ConfigurationClass实例的读取器
       if (this.reader == null) {
           this.reader = new ConfigurationClassBeanDefinitionReader(
                   registry, this.sourceExtractor, this.resourceLoader, this.environment,
                   this.importBeanNameGenerator, parser.getImportRegistry());
       }
       // 核心方法,将完全填充好的ConfigurationClass实例转化为BeanDefinition注册入IOC容器
       this.reader.loadBeanDefinitions(configClasses);
       // 添加到已经处理的集合中
       alreadyParsed.addAll(configClasses);
      
       candidates.clear();
       // 这里判断registry.getBeanDefinitionCount() > candidateNames.length的目的是为了知道reader.loadBeanDefinitions(configClasses)这一步有没有向BeanDefinitionMap中添加新的BeanDefinition
       // 实际上就是看配置类(例如AppConfig类会向BeanDefinitionMap中添加bean)
       // 如果有,registry.getBeanDefinitionCount()就会大于candidateNames.length
       // 这样就需要再次遍历新加入的BeanDefinition,并判断这些bean是否已经被解析过了,如果未解析,需要重新进行解析
       // 这里的AppConfig类向容器中添加的bean,实际上在parser.parse()这一步已经全部被解析了
       if (registry.getBeanDefinitionCount() > candidateNames.length) {
           String[] newCandidateNames = registry.getBeanDefinitionNames();
           Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
           Set<String> alreadyParsedClasses = new HashSet<>();
           for (ConfigurationClass configurationClass : alreadyParsed) {
               alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
           }
           // 如果有未解析的类,则将其添加到candidates中,这样candidates不为空,就会进入到下一次的while的循环中
           for (String candidateName : newCandidateNames) {
               if (!oldCandidateNames.contains(candidateName)) {
                   BeanDefinition bd = registry.getBeanDefinition(candidateName);
                   if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
                           !alreadyParsedClasses.contains(bd.getBeanClassName())) {
                       candidates.add(new BeanDefinitionHolder(bd, candidateName));
                   }
               }
           }
           candidateNames = newCandidateNames;
       }
      

      }
      while (!candidates.isEmpty());

      // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
      if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
      sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
      }

      if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
      // Clear cache in externally provided MetadataReaderFactory; this is a no-op
      // for a shared cache since it’ll be cleared by the ApplicationContext.
      ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
      }
      }

}
调用processConfigBeanDefinitions方法
1)查找到BeanFactory中的所有BeanDefinition,进行循环遍历
查到是否有configurationClass属性,有的话证明已经被处理过
checkConfigurationClassCandidate:(
判断是否有@Configuration注解修饰,
如果被@Configuration修饰且需要被代理则设置属性为full,
如果被Component、@ComponentScan、@Import、@ImportResource标注 或者被有@Bean注解修饰的
方法则设置为lite
如果都没有就返回false
检测是否有order注解修饰,有的话就设置order属性)
将被注解修饰的添加到 configCandidates 集合中
对有order修饰的BeanDefinition进行排序
2)判断是否为SingletonBeanRegistry 类型,因为此时的BeanDefinitionRegistry为DefaultListableBeanFactory类型,而它实现了DefaultListableBeanFactory,ConfigurableListableBeanFactory继承ConfigurableBeanFactory 所以这个判断可以进来,然后强转为SingletonBeanRegistry 类型来判断是否有自定义的命名生成策略

if (registry instanceof SingletonBeanRegistry) 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值