有位粉丝被 问到这样一个问题,说在Spring中,如果有两个ID相同的Bean,会不会报错?如果报错,会在哪个阶段报错?
这个问题也要分析具体的情况,才能完整的回答。我从三个方面来回答你的问题吧。
第一种情况是,如果采用的是XML文件进行配置,就不能存在两个相同的ID,Spring容器一启动就会报错。因为ID是Spring中Bean的唯一标识,所以,在启动Spring容器的时候就会去验证ID的唯一性,一旦发现重复就会报错,
这个错误是发生在Spring对XML文件进行解析的时候,然后转化为BeanDefinition的这个阶段。
但是,如果是在两个不同的XML文件里面,配置了两个相同的ID。那么IoC容器会在加载Bean的时候,用后者覆盖前者,所以,最终只保留一个。
第二种情况呢,是到了Spring 3.x版本以后,增加了注解配置的方式。我们可以通过@Configuration来声明一个配置类。然后使用@Bean注解来声明一个Bean。这就种方式就完全取代了XML的配置方式,那么在这种情况下,如果我们在同一个配置类里面声明多个相同ID的Bean,IoC容器就会只会注册第一个声明的Bean,后续重复名字的Bean相当于就会直接忽略。
@Configuration public class SpringConfiguration { @Bean( name = "service" ) public Service1 service1( ){ return new Service1( ); } @Bean( name = "service" ) public Service2 service2( ){ return new Service2( ); } }
比如,像这样一段代码,在Spring IoC容器中,就只会保留service1这个实例。后续相同名字的Bean就不会再加载,当然也不会报错。
第三种情况,如果使用@Autowired注解来实现依赖注入的话,它是根据类型来注入的。比如像这样一段代码
@Autowired private Service1 service1; @Autowired private Service2 service2;
因为IOC容器只有Service1的实例,所以启动的时候会提示找不到Service2这个实例。
第四种情况,再看这样一段代码:
@Resource( name="service" ) private Service1 service1; @Resource( name="service" ) private Service2 service2;
如果使用@Resource注解根据名称来实现依赖注入的话,那么在IoC容器中只能获取到Service1的实例,
于是,Spring会把Service1这个实例赋值给Service2,这个时候,就会提示类型不匹配的错误。
以上就是我对Spring中有两个ID相同的Bean的四种情况的分析。如果各位汤粉还有需要补充的,可以在评论区留言。