【SpringBoot源码分析】-Bean的加载过程 (3)

org.springframework.context.annotation.ConfigurationClassPostProcessor
org.springframework.context.event.DefaultEventListenerFactory
org.springframework.context.event.EventListenerMethodProcessor
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor

经过查看这些内置的类,只有ConfigurationClassPostProcessor和类加载相关。

ConfigurationClassPostProcessor

主要用于对@Configuration注解进行处理。在SpringBoot应用中,往往都是从一个Main函数开始,启动类上面也必须使用@SpringBootApplication注解来标明它的身份;因此@Configuration注解也代表着应用的起点;因在BeanFactoryPostProcessor被调用的时候是按照优先级来的,首先被调用的是BeanDefinitionRegistryPostProcessor,所以首先执行postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry)方法。

// ConfigurationClassPostProcessor.java public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { // ① 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); } // ③ this.registriesPostProcessed.add(registryId); // ④ processConfigBeanDefinitions(registry); }

① - 获取注册ID
② - 判断当前Processor是否被执行过
③ - 添加到已处理列表
④ - 处理配置相关的BeanDefinition

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { List<BeanDefinitionHolder> configCandidates = new ArrayList<>(); // 获取所有已注册的BeanDefinition,寻找具有@Configuration注解的类 String[] candidateNames = registry.getBeanDefinitionNames(); // 遍历所有的beanName for (String beanName : candidateNames) { // 根据名称找到BeanDefinition BeanDefinition beanDef = registry.getBeanDefinition(beanName); // 判断当前类是Full模式还是Lite模式,就为了打印个日志?No,查看日志内容,打印的是:当前类已经被当做一个configuration类被处理过。 // 那就意味着默认情况下它是没有设置ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE 这个属性的。 if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) { if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } // 判断当前处理的类是不是完整的配置类,也就是是否被@Configuration注解修饰,若被修饰则会给当前的BeanDefinition设置一个attribute(org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass = full) else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { // 加入配置候选列表 configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } // 若没有被@Configuration注解的类,直接返回 // Return immediately if no @Configuration classes were found if (configCandidates.isEmpty()) { return; } // 根据优先级排序 // Sort by previously determined @Order value, if applicable configCandidates.sort((bd1, bd2) -> { int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition()); int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition()); return Integer.compare(i1, i2); }); // 设置BeanNameGenerator用于生成稍后检测到的Bean的名称 // Detect any custom bean name generation strategy supplied through the enclosing application context SingletonBeanRegistry sbr = null; if (registry instanceof SingletonBeanRegistry) { sbr = (SingletonBeanRegistry) registry; if (!this.localBeanNameGeneratorSet) { BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR); if (generator != null) { this.componentScanBeanNameGenerator = generator; this.importBeanNameGenerator = generator; } } } if (this.environment == null) { this.environment = new StandardEnvironment(); } // 新建一个配置类解析器,用于解析所有@Configuration注解的类 // Parse each @Configuration class ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); // 将要被解析的配置类 Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates); // 已经被解析的配置类 Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size()); do { // ① 开始解析配置类 parser.parse(candidates); parser.validate(); // ② 获取解析到的配置类 Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses()); configClasses.removeAll(alreadyParsed); // ③ 构建Reader对象,为加载Bean做准备 Read the model and create bean definitions based on its content if (this.reader == null) { this.reader = new ConfigurationClassBeanDefinitionReader( registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry()); } // ④ 从配置类开始加载Bean this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); candidates.clear(); 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()); } 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(); } }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpfsdy.html