我有下面的bean定义
@Bean(name="producerConfig")
public Map<String, Object> producerConfig() {
和以下注入声明
@Service
@Component("...)
public class DataAssetSnapshotPublisherLive {
public SnapshotPublisherLive(..., @Qualifier("producerConfig") Map<String, Object> producerConfig) {
...
}
我希望producerPublisher
将被注入到producerPublisher
变量中,因为它具有相同的类型和限定符。
我在调试器中看到的不是这个,而是它被 Package 了
producerConfig = {LinkedHashMap@12556} size = 1
"producerConfig" -> {HashMap@12561} size = 27
key = "producerConfig"
value = {HashMap@12561} size = 27
也就是说,producerConfig
被新的HashMap
初始化,并且一个元素被添加到哈希Map中。
为什么以及如何防止这种情况?
1条答案
按热度按时间umuewwlo1#
这是一个例子的干预“ Spring 魔术”在意想不到的方式。
在这种情况下,map autowiring工作:如果你注入一个
Map<String, SomeClass>
,那么Spring会把它看作一个特例。你想注入所有覆盖SomeClass的注册bean。自动装配数组、集合和Map对于数组、集合或Map依赖类型,容器自动装配所有与声明的值类型匹配的bean。为此,Map键必须声明为String类型,该类型将被解析为相应的bean名称。这样的容器提供的集合将被排序,考虑目标组件的Ordered和@Order值,或者,单个匹配的目标bean也可以是一个一般类型的Collection或Map本身,以这种方式注入。
https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/beans/factory/annotation/Autowired.html
因此,从本质上讲,您在调试器(即LinkedHashMap)中获得的是所有bean的列表:
这些bean伴随着bean名称并按注册顺序排序,因此是LinkedHashMap。
请注意,如果map的key类型不是String,则不会发生这种情况。如果将
Map<String, Object>
替换为Map<Integer, Object>
,则行为将完全不同,并且您将像最初期望的那样只获得单个bean注入。关于“如何预防”:我不确定这个行为是否可以关闭,文档中没有任何说明。我认为最合理的解决方案是创建一个 Package 器类并注入它,而不是直接注入Map。