我使用春天已经有一段时间但今天早上我遇到了一些意想不到的行为。 由于我无法自己决定这是一个期望的功能还是我在这里提出的错误,希望我能得到一些很好的解释,为什么会发生这种情况。
简而言之,我在应用程序上下文中定义了多个bean,并使用utils创建了两个map bean:map name space,只有部分bean添加到这些map中。这两个地图具有完全相同的条目。
然后我自动连接这些地图。一条自动线使用@Autowired
注释完成,另一条使用@Resource
令我惊讶的是,使用@Autowired
注释的bean在上下文中获得了所有bean,而不仅仅是我在地图中专门放置的bean。使用@Resource
注释自动连接的另一个只有预期的两个条目。
我主要对以下方面感兴趣:
1.为什么在我当时的上下文中声明的所有bean都出现在@Autowired
地图而不是我添加的地图中
2.为什么@Resource
和@Autowired
的行为方式不同
以下是重现上述场景的工作代码。
这里有一些界面:
package my.testing.pkg;
public interface Foo {
void doStuff();
}
及其实施:
package my.testing.pkg;
public class FooImpl implements Foo {
@Override
public void doStuff() {}
}
spring配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:utils="http://www.springframework.org/schema/util"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
<bean id="foo_1" class="my.testing.pkg.FooImpl"/>
<bean id="foo_2" class="my.testing.pkg.FooImpl"/>
<bean id="foo_3" class="my.testing.pkg.FooImpl"/>
<bean id="foo_4" class="my.testing.pkg.FooImpl"/>
<utils:map id="fooMap1" map-class="java.util.HashMap">
<entry key="foo_1" value-ref="foo_1"/>
<entry key="foo_2" value-ref="foo_2"/>
</utils:map>
<utils:map id="fooMap2" map-class="java.util.HashMap">
<entry key="foo_1" value-ref="foo_1"/>
<entry key="foo_2" value-ref="foo_2"/>
</utils:map>
</beans>
重现行为的测试用例:
package my.testing.pkg;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
import java.util.Map;
import static org.junit.Assert.assertEquals;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "/test-context.xml")
public class SpringMapCreatingTest {
@Autowired
private Map<String, Foo> fooMap1;
@Resource
private Map<String, Foo> fooMap2;
@Test
public void shouldInjectATwoEntriesMap() throws Exception {
assertEquals("fooMap1 should have to entries", 2, fooMap1.size());
assertEquals("fooMap2 map should have to entries", 2, fooMap1.size());
}
}
提前感谢您的澄清。
答案 0 :(得分:0)
地图/列表不会被处理为&#34;标准&#34;豆类注射。
看看这些问题:Can spring @Autowired Map? https://stackoverflow.com/a/13914052/1517816
HIH
答案 1 :(得分:0)
检查spring docs,提示部分:
本身定义为集合或地图类型的bean不能 通过@Autowired注入,因为类型匹配不正确 适用于他们。将@Resource用于此类bean
所以最好使用@Resource而不是@Autowired for maps
答案 2 :(得分:0)
发生了以下情况:
Foo
的映射。当你在bean列表上自动装配时会发生同样的行为,Spring将注入实现该接口的所有bean。fooMap2
并将其注入。