基于Bean ID与primary属性覆盖Spring Bean的疑问
关于Spring同ID Bean覆盖与primary属性的疑问解答
这个问题问得很到位,很多人容易把primary属性的作用和Bean ID冲突的覆盖逻辑搞混,我来给你掰扯清楚:
首先明确同ID Bean的核心处理逻辑:
Spring容器中,Bean的id是唯一标识符,当容器尝试注册一个已经存在相同id的Bean时,后注册的Bean会直接覆盖先注册的——这个逻辑和primary属性完全无关。哪怕你给先注册的Bean加primary="true",只要后注册的Bean和它同ID,照样会被覆盖。primary属性的真实作用:
它是用来解决同类型、不同ID的Bean注入歧义问题的。比如你有两个类型都是bar的Bean,id分别是foo1和foo2,当你用@Autowired自动注入bar类型的Bean时,Spring不知道选哪个,这时候给其中一个Bean加上primary="true",Spring就会优先选择这个标记了primary的Bean。回到你的场景:
你原来的情况是配置B加载顺序晚于A,所以B的foo覆盖了A的。但如果给B的foo加primary="true",并不能确保它“始终”覆盖A的。因为如果哪天配置加载顺序变了(比如某些配置类的扫描顺序调整、XML文件加载顺序改动),只要A的加载顺序跑到B后面,A的foo还是会覆盖B的——毕竟同ID的覆盖逻辑只看注册顺序,和primary没关系。更稳定的解决方案建议:
如果想稳定让B的foo成为最终生效的Bean,更可靠的方式是:- 确保配置B的加载顺序始终在A之后(比如在XML中通过
import标签明确顺序,或者在注解配置中通过@DependsOn、配置类的扫描顺序控制); - 如果允许的话,把A中的
fooBean的primary设为false,同时给B的foo设为true,但前提是两个Bean的ID不同(比如A的id是fooA,B的是fooB),这样通过primary来控制注入优先级,避免ID冲突的问题。
- 确保配置B的加载顺序始终在A之后(比如在XML中通过
内容的提问来源于stack exchange,提问作者njk2015
相关产品推荐
相关产品推荐

