Spring框架自动装配Map键值异常问题求助
为什么Spring自动装配Map后键变成了Bean类名小写?
你遇到的这个问题,核心是Spring自动装配Map的默认行为和你预期的不一致。
当你用@Autowired注入Map<String, DataObject>时,Spring有个默认规则:如果泛型的Value类型(这里是DataObject)是一个可被Spring管理的Bean类型,Spring会自动扫描容器中所有类型为DataObject的Bean,把它们的**Bean名称(默认是类名首字母小写,比如BasicDataObject变成basicDataObject)**作为键,Bean实例作为值,组装成一个新的Map注入给你——而不是注入你自己在dataObjects()方法里创建的那个Map!
这就解释了为什么你自己创建Map时打印键是正常的(比如dat1),但注入后键变成了类名小写:Spring压根没注入你手动构建的那个Map,而是帮你生成了一个包含所有DataObject类型Bean的新Map。
解决方案1:用@Qualifier指定要注入的Map Bean
给你手动创建的Map Bean起个明确的名称,然后在注入时用@Qualifier指定这个名称,告诉Spring要注入的是你自己的那个Map,而不是它自动生成的:
修改Bean定义:
@Bean(name = "customDataObjects") // 给Map Bean起个专属名称 public Map<String, DataObject> dataObjects() { Map<String, DataObject> m = new HashMap<>(); for(Map.Entry<String, String> e : properties.entrySet()){ m.put(e.getKey(), loadDataObject(e.getValue())); } LOG.info("m contains "+m); return m; // 别忘了return语句,否则Spring无法创建该Bean }
修改注入代码:
@Component @Import(AppConf.class) class DataObjectProcessor{ @Autowired @Qualifier("customDataObjects") // 指定要注入的Map Bean名称 private Map<String, DataObject> dataObjects; }
解决方案2:用@Resource代替@Autowired
@Resource注解默认是按名称匹配Bean,而不是按类型。因为你的Map Bean的默认名称就是方法名dataObjects(如果没指定name的话),和你注入时的变量名一致,所以直接用@Resource就能准确注入你自己创建的Map:
@Component @Import(AppConf.class) class DataObjectProcessor{ @Resource // 代替@Autowired,按名称匹配Bean private Map<String, DataObject> dataObjects; }
内容的提问来源于stack exchange,提问作者BreenDeen
相关产品推荐
相关产品推荐

