java 为什么@Autowired(required=false) 在@Configuration bean 上不起作用?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25157293/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Why @Autowired(required=false) do not work on @Configuration beans?
提问by Christian Sisti
Let explain with an example:
让我们用一个例子来解释:
Having this bean:
有这个豆子:
public class Foo {
private String name;
Foo(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
}
And this service:
而这项服务:
public class FooService {
private Foo foo;
FooService(Foo foo) {
this.foo = foo;
}
Foo getFoo() {
return this.foo;
}
}
Given the following Spring configuration:
鉴于以下 Spring 配置:
@Configuration
public class SpringContext {
// @Bean
// Foo foo() {
// return new Foo("foo");
// }
@Bean
@Autowired(required = false)
FooService fooService(Foo foo) {
if (foo == null) {
return new FooService(new Foo("foo"));
}
return new FooService(foo);
}
}
For completeness here is a simple unit test:
为了完整起见,这里是一个简单的单元测试:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringContext.class})
public class SpringAppTests {
@Autowired
private FooService fooService;
@Test
public void testGetName() {
Assert.assertEquals("foo", fooService.getFoo().getName());
}
}
Then loading the context will throw a NoSuchBeanDefinitionException (Foo).
然后加载上下文将抛出 NoSuchBeanDefinitionException (Foo)。
Can anyone see anything wrong/missing on this example, or provide me a reason for that?
任何人都可以在这个例子中看到任何错误/遗漏的地方,或者给我一个理由吗?
Thank you! Christian
谢谢!基督教
回答by René Link
In addition to the other answers:
除了其他答案:
The problem is that spring does not take the required=false
into account when injecting parameters. See ConstructorResolver
问题是springrequired=false
在注入参数时没有考虑。看ConstructorResolver
return this.beanFactory.resolveDependency(
new DependencyDescriptor(param, true), beanName, autowiredBeanNames, typeConverter);
The second argument is always true
:
第二个参数总是true
:
public DependencyDescriptor(MethodParameter methodParameter, boolean required)
public DependencyDescriptor(MethodParameter methodParameter, boolean required)
EDIT:Spring uses the ConstructorResolver
for
编辑:Spring 使用ConstructorResolver
for
"real" constuctor injection
@Autowired(required=false) // required=false WILL NOT WORK public FooService(Foo foo){ ... }
factory methods
@Bean @Autowired(required=false) // required=false WILL NOT WORK FooService fooService(Foo foo) { if (foo == null) { return new FooService(new Foo("foo")); } return new FooService(foo); }
“真正的”构造函数注入
@Autowired(required=false) // required=false WILL NOT WORK public FooService(Foo foo){ ... }
工厂方法
@Bean @Autowired(required=false) // required=false WILL NOT WORK FooService fooService(Foo foo) { if (foo == null) { return new FooService(new Foo("foo")); } return new FooService(foo); }
Thus in both cases the required
attribute is ignored.
因此,在这两种情况下,该required
属性都被忽略。
回答by Ben Green
You have your syntax wrong. The @Autowired(required = false)
would need to be relating to the Foo
.
你的语法错误。在@Autowired(required = false)
将需要有关的Foo
。
For example:
例如:
@Configuration
public class SpringContext {
@Autowired(required = false)
private Foo foo;
@Bean
FooService fooService() {
if (foo == null) {
return new FooService(new Foo("foo"));
}
return new FooService(foo);
}
}
回答by Ralph
Try
尝试
@Configuration
public class SpringContext {
// @Bean
// Foo foo() {
// return new Foo("foo");
// }
@Autowired(required = false)
Foo foo;
@Bean
FooService fooService() {
if (this.foo == null) {
return new FooService(new Foo("foo"));
}
return new FooService(this.foo);
}
}