@Autowired 或 private final
@Autowired or private final
我的问题很简单。哪种方法更有效?
方法一:
@Autowired
private CustomerRepository customerRepo;
方法二:
private final CustomerRepository custormerRepo;
public StudentService(CustomerRepository customerRepo) {
this.customerRepo = customerRepo;
}
正如我所见,method2 中的 DI 更新了。但是我想问你我应该用哪一个?
在您的主要代码中,您应该使用方法 2,因为不推荐使用字段注入(方法 1)。 (原因见here)
在你的测试代码中,使用方法一就可以了。
使用构造函数注入,Spring也推荐
TL;DR: 方法 2 更加灵活。
方法一是字段注入的例子,方法二是构造注入的例子。
字段注入有一些构造函数注入避免的缺点。以下是构造函数注入的一些优点:
不变性:
你不能这样做很简单Java:
@Autowired
private final CustomerRepository customerRepo;
// No constructor that sets "customerRepo".
因此,Spring 提供构造函数注入:
private final CustomerRepository customerRepo;
@Autowired
public StudentService(final CustomerRepository customerRepo) {
this.customerRepo = customerRepo;
}
不变性有时是首选。一个原因是它有助于 thread-safety.
就我个人而言,我遵循规则,“如果它是最终的,它应该是最终的。”
测试:
您不需要反射来设置依赖项。是的,许多模拟框架会为您处理这个问题,但是通过构造函数注入,您可以选择在构造函数上调用 new
。
恶心NullPointerException
s:
一个对象是通过调用它的构造函数来创建的,对吧?我们通常希望我们的参数在传入时为 non-null。通过构造函数注入,Spring IoC container 确保构造函数中传递的所有参数在传递给构造函数之前可用。
除了其他答案所说的不变性之外,构造函数注入的另一个好处是可以避免字段未初始化的NPE。使用自动装配,从测试中,您将创建 class 然后必须记住设置该字段。使用构造函数注入,你不能不初始化字段。这在 Kotlin 中更为突出,其中自动装配的字段被声明为 lateinit var
并且如果在初始化之前使用则抛出运行时异常。但是可以将构造函数参数声明为非空类型,这甚至会阻止您显式传递空值。
我建议你提出更好的建议。通过使用 Lombok 库的 @RequiredArgConstructor
,您可以避免样板代码。如果您想知道为什么 @Autowired
不被推荐,因为当您想在您的应用程序中编写单元测试时会出现问题,如果您使用 @Autowired
.
我的问题很简单。哪种方法更有效?
方法一:
@Autowired
private CustomerRepository customerRepo;
方法二:
private final CustomerRepository custormerRepo;
public StudentService(CustomerRepository customerRepo) {
this.customerRepo = customerRepo;
}
正如我所见,method2 中的 DI 更新了。但是我想问你我应该用哪一个?
在您的主要代码中,您应该使用方法 2,因为不推荐使用字段注入(方法 1)。 (原因见here)
在你的测试代码中,使用方法一就可以了。
使用构造函数注入,Spring也推荐
TL;DR: 方法 2 更加灵活。
方法一是字段注入的例子,方法二是构造注入的例子。
字段注入有一些构造函数注入避免的缺点。以下是构造函数注入的一些优点:
不变性:
你不能这样做很简单Java:
@Autowired
private final CustomerRepository customerRepo;
// No constructor that sets "customerRepo".
因此,Spring 提供构造函数注入:
private final CustomerRepository customerRepo;
@Autowired
public StudentService(final CustomerRepository customerRepo) {
this.customerRepo = customerRepo;
}
不变性有时是首选。一个原因是它有助于 thread-safety.
就我个人而言,我遵循规则,“如果它是最终的,它应该是最终的。”
测试:
您不需要反射来设置依赖项。是的,许多模拟框架会为您处理这个问题,但是通过构造函数注入,您可以选择在构造函数上调用 new
。
恶心NullPointerException
s:
一个对象是通过调用它的构造函数来创建的,对吧?我们通常希望我们的参数在传入时为 non-null。通过构造函数注入,Spring IoC container 确保构造函数中传递的所有参数在传递给构造函数之前可用。
除了其他答案所说的不变性之外,构造函数注入的另一个好处是可以避免字段未初始化的NPE。使用自动装配,从测试中,您将创建 class 然后必须记住设置该字段。使用构造函数注入,你不能不初始化字段。这在 Kotlin 中更为突出,其中自动装配的字段被声明为 lateinit var
并且如果在初始化之前使用则抛出运行时异常。但是可以将构造函数参数声明为非空类型,这甚至会阻止您显式传递空值。
我建议你提出更好的建议。通过使用 Lombok 库的 @RequiredArgConstructor
,您可以避免样板代码。如果您想知道为什么 @Autowired
不被推荐,因为当您想在您的应用程序中编写单元测试时会出现问题,如果您使用 @Autowired
.