浏览Spring Javaconfig参考文档 http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/html/beans.html 我发现了一些令人困惑的部分......
在 " 5.12.4使用@Configuration注释" 下,它说:
"当@Beans彼此依赖时,表达该依赖关系就像让一个bean方法调用另一个一样简单:
@Configuration
public class AppConfig {
@Bean
public Foo foo() {
return new Foo(bar());
}
@Bean
public Bar bar() {
return new Bar();
}
}
在上面的例子中,foo bean通过构造函数注入接收对bar的引用。"
好吧,如果一切都是无状态的,那可能并不重要,但如果你有上面的配置,然后在你的应用程序中做:
@Autowired
private Foo foo;
@Autowired
private Bar bar;
检查bean的hashCodes,结果是,您的私有变量 bar 将引用 Bar 的不同实例而不是一个由 foo 使用的, 这可能不是你所期望的,对吗?
我想说正常模式应该是:
@Configuration
public class AppConfig {
@Bean
public Bar bar() {
return new Bar();
}
@Autowired Bar bar;
@Bean
public Foo foo() {
return new Foo(bar);
}
}
现在,当您在应用中自动装配两个bean时,您只会创建一个Bar实例。
我是否遗漏了某些内容,或者我是否认为文档存在缺陷?
然后,再进一步,在 &#34部分下;有关基于Java的配置如何在内部工作的更多信息" 看起来他们试图澄清"这个问题:
@Configuration
public class AppConfig {
@Bean
public ClientService clientService1() {
ClientServiceImpl clientService = new ClientServiceImpl();
clientService.setClientDao(clientDao());
return clientService;
}
@Bean
public ClientService clientService2() {
ClientServiceImpl clientService = new ClientServiceImpl();
clientService.setClientDao(clientDao());
return clientService;
}
@Bean
public ClientDao clientDao() {
return new ClientDaoImpl();
}
}
现在,不幸的是,这个配置甚至不能在运行时加载,因为有两个相同类型的bean,ClientService,没有区别属性,所以得到异常
org.springframework.beans.factory.NoUniqueBeanDefinitionException:
No qualifying bean of type [.....] is defined:
expected single matching bean but found 2
但是即使我们稍微改变了这个例子,并给出了前两个bean不同的类型,
@Bean
public ClientService1 clientService1() {...clientDao()...}
@Bean
public ClientService2 clientService2() {...clientDao()...}
@Bean
public ClientDao clientDao() {
return new ClientDaoImpl();
}
这仍然是不正确的,因为 - 与文本声称的相反 - 我们仍然会创建3个不同的ClientDaoImpl实例, 当自动装配所有3个豆时。
再次,我完全错过了什么,或者文档真的像我看来一样糟糕?
编辑:添加了一个演示,演示了我看到的问题:
bean ServiceA , 和两个bean ServiceB1 , ServiceB2 构造函数注入 ServiceA 。
然后两个测试类 Config01Test 和 Config02Test 除配置外完全相同。第一次测试PASSES,第二次失败是因为唯一性 - 断言。
答案 0 :(得分:8)
检查配置类上是否有@Configuration
注释。至少在Config01
和Config02
类中缺少您的演示。如果我将它们添加到这些类中,测试就会通过。
答案 1 :(得分:0)
我自己没有测试这个例子,这应该确保你在整个应用程序上下文中只有一个Bar实例
@Configuration
public class AppConfig {
@Bean
public Foo foo(Bar bar) {
return new Foo(bar);
}
@Bean
public Bar bar() {
return new Bar();
}
}