Spring|Spring Boot @Component @Configuration 同时声明一个对象会怎样呢()

先贴出示例:
Spring|Spring Boot @Component @Configuration 同时声明一个对象会怎样呢()
文章图片

Spring|Spring Boot @Component @Configuration 同时声明一个对象会怎样呢()
文章图片

接下来开始分析过程,启动项目,会发现ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry()执行我们声明的目标类:
Spring|Spring Boot @Component @Configuration 同时声明一个对象会怎样呢()
文章图片

Spring|Spring Boot @Component @Configuration 同时声明一个对象会怎样呢()
文章图片

图1-2

public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { List configCandidates = new ArrayList<>(); String[] candidateNames = registry.getBeanDefinitionNames(); for (String beanName : candidateNames) { BeanDefinition beanDef = registry.getBeanDefinition(beanName); if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) { if (logger.isDebugEnabled()) { logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); } } 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 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 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(); }// Parse each @Configuration class //创建ConfigurationClassParser类,用来解析带有@Configuration的类 ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); Set candidates = new LinkedHashSet<>(configCandidates); Set alreadyParsed = new HashSet<>(configCandidates.size()); do { //执行解析逻辑 parser.parse(candidates); parser.validate(); //保存所有带@Configuration的类 Set configClasses = new LinkedHashSet<>(parser.getConfigurationClasses()); configClasses.removeAll(alreadyParsed); // Read the model and create bean definitions based on its content if (this.reader == null) { //声明@configuration读取类 this.reader = new ConfigurationClassBeanDefinitionReader( registry, this.sourceExtractor, this.resourceLoader, this.environment, this.importBeanNameGenerator, parser.getImportRegistry()); } //加载 this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); candidates.clear(); if (registry.getBeanDefinitionCount() > candidateNames.length) { String[] newCandidateNames = registry.getBeanDefinitionNames(); Set oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames)); Set 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(); } }

其中reader.loadBeanDefinitions(configClasses),最终调用loadBeanDefinitionsForConfigurationClass()
private void loadBeanDefinitionsForConfigurationClass( ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) { for (BeanMethod beanMethod : configClass.getBeanMethods()) { //加载@Configuration类中的带@Bean的方法 loadBeanDefinitionsForBeanMethod(beanMethod); } }

private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) { //将@Bean的所在方法的类,注册进DefaultListBeanFactory的beanDefinitionMap中 this.registry.registerBeanDefinition() }

【Spring|Spring Boot @Component @Configuration 同时声明一个对象会怎样呢()】DefaultListBeanFactory.registerBeanDefinition(); 具体细节
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { BeanDefinition oldBeanDefinition; //因为之前的parser已经解析到userManager,此时解析UserConfig中的UserManager会发现 oldBeanDefinition 不为空; oldBeanDefinition = this.beanDefinitionMap.get(beanName); if (oldBeanDefinition != null) { if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName + "': There is already [" + oldBeanDefinition + "] bound."); } else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (this.logger.isWarnEnabled()) { this.logger.warn("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(oldBeanDefinition)) { if (this.logger.isInfoEnabled()) { this.logger.info("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } else { if (this.logger.isDebugEnabled()) { this.logger.debug("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + oldBeanDefinition + "] with [" + beanDefinition + "]"); } } //新的beanDefinition会替换为老的beanDefinition this.beanDefinitionMap.put(beanName, beanDefinition); } }

结果就是:
Spring|Spring Boot @Component @Configuration 同时声明一个对象会怎样呢()
文章图片

oldBeanDefinition被替换掉;

    推荐阅读