问题描述
何时在Spring中使用构造函数注入?
When to use constructor injection in Spring?
我听说构造函数注入在您绝对必须在使用组件之前必须拥有依赖项类的实例时特别有用.但这是什么意思?
I heard that constructor injection is particularly useful when you absolutely must have an instance of the dependency class before your component is used. But what does it mean?
在下面的时刻,有人可以用一些简单的例子向我解释一下吗?
Can anybody explain me with some simple examples the following moments:
- 使用构造函数注入有什么好处?
- 什么是 dynamic 构造函数注入?
- What are the benefits that I will get using constructor injection?
- What is dynamic constructor injection?
推荐答案
正确的方法是尽可能使用构造函数注入.由于这一点,很明显,对象依赖关系是什么,如果不提供所需的全部内容,则无法创建对象依赖关系.
The correct approach is to use constructor injection whenever it's possible. Thanks to that it's clear what are the object dependencies and you are not able to create one if you do not provide all that are required.
按如下所示使用构造函数注入.
Use constructor injection as below.
public class ProjectService {
private final ProjectRepository projectRepository;
private final TaskRepository taskRepository;
public ProjectService(TaskRepository taskService, ProjectRepository projectService) {
Assert.notNull(taskService);
Assert.notNull(projectService);
this.taskRepository = taskService;
this.projectRepository = projectService;
}
public Project load(Long projectId) {
return projectRepository.findById(projectId);
}
}
-
final
字段确保在对象初始化后不更改依赖项 -
Assert.notNull
确保没有放置空值而不是真实对象. final
fields make sure that dependencies are not changed after object is initializedAssert.notNull
makes sure that you don't put null values instead of real objects.
当您使用setter注入或字段注入时,您的API会让您创建处于错误状态的对象.考虑一个例子:
When you use setter injection or field injection your API lets you create object in incorrect state. Consider an example:
public class ProjectService {
private ProjectRepository projectRepository;
private TaskRepository taskRepository;
public Project load(Long projectId) {
return projectRepository.findById(projectId);
}
@Autowired
public void setProjectRepository(ProjectRepository projectRepository) {
this.projectRepository = projectRepository;
}
@Autowired
public void setTaskRepository(TaskRepository taskRepository) {
this.taskRepository = taskRepository;
}
}
ProjectService projectService = new ProjectService();
projectService.load(1L); // NullPointerException is thrown
对于所有非可选的依赖项,您可以使用setter注入.在Oliver Gierke(春季数据负责人)博客上了解更多信息: http://olivergierke.de/2013/11/why-field-injection-is-evil/
For all not optional dependencies you can use setter injection.Read more on Oliver Gierke (Spring Data lead) blog: http://olivergierke.de/2013/11/why-field-injection-is-evil/
更新15.01.2019
从Spring 4.3开始,如果仅存在单个构造函数,则无需在构造函数上放置 @Autowired
注释.
Starting from Spring 4.3 there is no need to put @Autowired
annotation on the constructor if only single constructor is present.
这篇关于什么时候在Spring中使用构造函数注入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!