Spring之两个bean的name相同会报错吗
首先要回答这个问题要看spring什么版本,以及使用的是什么方式初始化spring容器。先说结论,如果是xml的方式,还要分两种情况
1 所有的bean都定义在同一个xml中,这种情况下会直接报错
2 两个相同名字的bean定义在两个xml文件中,一个xml文件通过import进行引用另一个,这种方式会进行覆盖。
不过,现在使用spring基本没有在使用xml方式的了,都是通过@Configuration的方式,比如我们有如下的代码
package com.example.demo.configuration; import com.example.demo.beans.Book; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class AnnotationConfiguration { public AnnotationConfiguration() { System.out.println("初始化"); } @Bean("book1") public Book book() { Book book=new Book(); book.setName("java++"); return book; } @Bean("book1") public Book book1() { Book book=new Book(); book.setName("java"); return book; } }
下面来分析@Bean的解析过程
1 ConfigurationClassParser.doProcessConfigurationClass 代码片段
// Process individual @Bean methods Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass); for (MethodMetadata methodMetadata : beanMethods) { configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass)); }
retrieveBeanMethodMetadata方法在这里就不详细分析了,结论就是会把两个@Bean注解的方法包成MethodMetadata,注意这里会包成两个方法
2 ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod
第一步做的只是解析@Configuration类,还没有进行BeanDefinition的生成。
真正进行生成BeanDefinition的地方是在 ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForBeanMethod
// Has this effectively been overridden before (e.g. via XML)? if (isOverriddenByExistingDefinition(beanMethod, beanName)) { if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) { throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(), beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() + "' clashes with bean name for containing configuration class; please make those names unique!"); } return; }
其中的代码段,如果一个beanName已经被处理过了,也就是 isOverriddenByExistingDefinition 返回为true
就直接return。
抛异常的地方的逻辑是,@Bean所在的@Configuration的classname是否和beanName相同,我们这里的classname是 AnnotationConfiguration
所以一般情况下都不会走到抛异常的逻辑里