@Autowired注释使我们的生活更轻松。 如果我们在类的属性上使用它,也可能导致代码量减少。 我们既不需要构造函数也不需要setter方法。 乍一看看起来很棒,但好处很少是没有成本的。
今天,我想让您知道必须支付的费用。
@Autowired(必填= false)
默认情况下,@ Autowired批注将required元素设置为true,这意味着需要注释的依赖项。 但是,我们可以关闭默认行为,并将依赖项设为可选,如下所示:
@Autowired(required=false)
private Dependency dependency;
它很有用,并且由于并非总是需要所有依赖项,因此引入这种可能性是合理的。
那么以这种方式注释依赖项又是什么问题呢?
让我们看一下代码:
class SomeClass {@Autowired private DependencyA dependencyA;@Autowired private DependencyB dependencyB;@Autowired(required=false)private DependencyC dependencyC;@Autowired(required=false)private DependencyD dependencyD;
}
我们可以创建具有以下依赖关系的SomeClass实例(允许所有组合):
- DependencyA,DependencyB
- DependencyA,DependencyB,DependencyC
- DependencyA,DependencyB,DependencyD
- DependencyA,DependencyB,DependencyC,DependencyD
这一切都很好,但是您确定所有这些组合确实可用并且正确吗? 如果班级作者只考虑1和4怎么办?
可选的依赖项-正确执行!
如果我们正在考虑上一段中提供的示例,则对于所提问题有两个可能的答案:
- 所有组合都是可能的。
- 组合的子集是可能的。
如果所有组合都可行,我将保持原样。 如果没有什么可以出错的,并且对象的每个状态都是正确的,那么我们的代码就具有足够的描述性。 它显然允许任何事情,因此我们可以假设我们将做的任何事情都会导致我们可以使用的对象的创建。
第二点-组合的子集呢?
假定仅从点1和点4开始创建状态的对象是有效对象。 照原样保留代码可能会导致对象的错误使用。 我们允许创建处于无效状态(第2点和第3点)的对象。 我们对此可以做什么?
在那种情况下,我认为我们应该删除@Autowired注释。 为了代码的可读性和设计质量,最好使用构造函数:
class SomeClass {private DependencyA dependencyA;private DependencyB dependencyB;private DependencyC dependencyC;private DependencyD dependencyD;public SomeClass(DependencyA dependencyA, DependencyB dependencyB) {this.dependencyA = dependencyA;this.dependencyB = dependencyB;}public SomeClass(DependencyA dependencyA, DependencyB dependencyB, DependencyC dependencyC, DependencyD dependencyD) {this(dependencyA, dependencyB);this.dependencyC = dependencyC;this.dependencyD = dependencyD;}
}
有了这段代码,您就知道了一切。 您知道创建正确对象所需的依赖项。
保持警惕!
本文无意让您相信最好不要使用@Autowired(required = false)。 其目的是使您知道必须支付的费用。
您必须保护自己的设计,必须保护对象不变式,并且不应该允许对象处于无效状态。 当然,您可以添加文档或注释,但是如果我们已经有了该语言提供的语义,可以使我们无需付出额外的努力即可使用它。
翻译自: https://www.javacodegeeks.com/2016/03/autowired-optional-dependencies.html