spring 如何将@Autowired 构造函数参数单独设置为“required=false”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/42135102/
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
How to set @Autowired constructor params as "required=false" individually
提问by jcgarcia
I'm using the @Autowiredannotation under a @Configurationclass constructor.
我@Autowired在@Configuration类构造函数下使用注释。
@Configuration
public class MyConfiguration {
private MyServiceA myServiceA;
private MyServiceB myServiceB
@Autowired
public MyConfiguration(MyServiceA myServiceA, MyServiceB myServiceB){
this.myServiceA = myServiceA;
this.myServiceB = myServiceB;
}
}
As the Spring documentation sais, I'm able to declare whether the annotated dependency is required.
正如Spring 文档所说,我可以声明是否需要带注释的依赖项。
If I mark the @Autowiredannotation under the constructor as required=false, I'm saying that the two services to be autowired are not required (as the Spring documentation sais):
如果我@Autowired将构造函数下的注释标记为required=false,我是说不需要自动装配的两个服务(如 Spring 文档所说):
@Autowired(required = false)
public MyConfiguration(MyServiceA myServiceA, MyServiceB myServiceB){
this.myServiceA = myServiceA;
this.myServiceB = myServiceB;
}
From Spring documentation:
来自 Spring 文档:
In the case of multiple argument methods, the 'required' parameter is applicable for all arguments.
在多参数方法的情况下,'required' 参数适用于所有参数。
How can I set the requiredattribute to each constructor parameter individually? Is necessary to use @Autowiredannotation under every field?
如何分别required为每个构造函数参数设置属性?是否有必要@Autowired在每个字段下使用注释?
Regards,
问候,
回答by Strelok
If you're using Java 8 and Spring Framework 4, you can use Optional.
如果您使用的是 Java 8 和 Spring Framework 4,则可以使用Optional.
@Autowired
public MyConfiguration(Optional<MyServiceA> myServiceA, Optional<MyServiceB> myServiceB){
myServiceA.ifPresent(service->{this.myServiceA = service});
myServiceB.ifPresent(service->{this.myServiceB = service});
}
回答by Daniel Olszewski
Explicit approach
显式方法
Basically, you have a bean which have some required and optional dependencies. The recommended way of handling this scenario, not only configuration beans but any other, is to create a constructor only for mandatory dependencies and use setter injection for optional ones.
基本上,您有一个 bean,它具有一些必需和可选的依赖项。处理这种情况的推荐方法,不仅是配置 bean,还有任何其他情况,是仅为强制依赖项创建构造函数,并为可选依赖项使用 setter 注入。
public class MyConfiguration {
private final MyServiceA myServiceA;
private MyServiceB myServiceB
@Autowired
public MyConfiguration(MyServiceA myServiceA){
this.myServiceA = myServiceA;
}
@Autowired(required = false)
public void setMyServiceB(MyServiceB myServiceB) {
this.myServiceB = myServiceB;
}
}
With this approach you can easily unit test the class without necessity for any mocking library. You can create an object in testing state using the constructor and optional setters.
使用这种方法,您可以轻松地对类进行单元测试,而无需任何模拟库。您可以使用构造函数和可选的 setter 创建处于测试状态的对象。
Putting @Autowired(required = false)directly on the field and removing the setter will also work, but since you are using the constructor injection, I assume you want to state dependencies more explicitly.
把@Autowired(required = false)直接在球场上和去除二传也将工作,但由于您使用的是构造器注入,我想你想的状态依存更加明确。
Additional idea
额外的想法
You can also consider using the Optional type to wrap not mandatory dependencies. It is common among developers to assume that if a class has a property, it should be set, which is obviously not right in your scenario. To mark the possibility of absence for particular dependencies more clear you probably can use Optional:
您还可以考虑使用 Optional 类型来包装非强制依赖项。开发人员通常假设如果一个类有一个属性,就应该设置它,这在您的场景中显然是不正确的。要更清楚地标记特定依赖项不存在的可能性,您可能可以使用 Optional:
public class MyConfiguration {
private final MyServiceA myServiceA;
private Optional<MyServiceB> myServiceB
@Autowired
public MyConfiguration(MyServiceA myServiceA){
this.myServiceA = myServiceA;
this.myServiceB = Optional.empty();
}
@Autowired(required = false)
public void setMyServiceB(MyServiceB myServiceB) {
this.myServiceB = Optional.ofNullable(myServiceB);
}
}
Some people are against using the Optionaltype for class properties (mainly because of this answer from Brian Goetz), but at the end of the day it should be the decision made by the whole team that is going to work on the project.
有些人反对将Optional类型用于类属性(主要是因为来自 Brian Goetz的这个回答),但归根结底,应该由整个团队做出决定来处理项目。
回答by Czar
Since Spring 4.3.0.RC1 you can do this:
从 Spring 4.3.0.RC1 开始,你可以这样做:
public MyConfiguration(MyServiceA myServiceA, @Autowired(required = false) MyServiceB myServiceB){
this.myServiceA = myServiceA;
this.myServiceB = myServiceB;
}
As ElementType.PARAMETERwas added as annotation target.
AsElementType.PARAMETER被添加为注释目标。
From Spring 5.0 @Autowired(required = false)can also be replaced by @Nullableor a Kotlin nullable type can be used without any annotation, e.g. MyServiceB?
从 Spring 5.0 开始@Autowired(required = false),也可以替换@Nullable为 Kotlin 可空类型,或者可以在没有任何注释的情况下使用,例如MyServiceB?
回答by Хакан Хюсеин
As of Spring Framework 5.0, you can also use a @Nullable annotation (of any kind in any package?—?for example, javax.annotation.Nullable from JSR-305):
从 Spring Framework 5.0 开始,您还可以使用 @Nullable 注释(任何包中的任何类型?-?例如,来自 JSR-305 的 javax.annotation.Nullable):
@Configuration
public class MyConfiguration {
private MyServiceA myServiceA;
private MyServiceB myServiceB
@Autowired
public MyConfiguration(@Nullable MyServiceA myServiceA, MyServiceB myServiceB){
this.myServiceA = myServiceA;
this.myServiceB = myServiceB;
}
}

