Java 什么是现场注入,如何避免?
我在一些关于SpringMVC和Portlet的帖子中读到,不推荐使用字段注入。据我所知,字段注入是指使用Java 什么是现场注入,如何避免?,java,spring-mvc,dependency-injection,portlet,autowired,Java,Spring Mvc,Dependency Injection,Portlet,Autowired,我在一些关于SpringMVC和Portlet的帖子中读到,不推荐使用字段注入。据我所知,字段注入是指使用@Autowired注入Bean,如下所示: @Component public class MyComponent { @Autowired private Cart cart; } 在我的研究期间,我还阅读了有关构造函数注入的内容: 这两种注射的优点和缺点是什么 编辑1:因为这个问题被标记为重复的,所以我检查了它。因为问题和答案中都没有任何代码示例,我不清楚我的猜测是
@Autowired
注入Bean,如下所示:
@Component
public class MyComponent {
@Autowired
private Cart cart;
}
在我的研究期间,我还阅读了有关构造函数注入的内容:
这两种注射的优点和缺点是什么
编辑1:因为这个问题被标记为重复的,所以我检查了它。因为问题和答案中都没有任何代码示例,我不清楚我的猜测是否正确,我使用的是哪种注入类型 味道的问题。这是你的决定 但我可以解释为什么我从不使用构造函数注入
@Service
、@Repository
和@Controller
bean实现构造函数。我的意思是,大约有40-50个豆子或更多。每次如果我添加一个新字段,我都必须扩展构造函数。不,我不想要也不必编辑#1: Vojtech Ruzicka说: 类具有太多依赖项,并且可能违反了单个 责任原则,应该重构 对。理论与现实。 例如:
DashboardController
映射到单个路径*:8080/dashboard
Mydashboard Controller
从其他服务收集大量信息,并将其显示在仪表板/系统概览页面中。我需要一个控制器。因此,我必须只保护这一条路径(基本身份验证或用户角色筛选器)
编辑#2:
因为每个人都关注构造函数中的8个参数。。。这是一个真实的示例—客户遗留代码。我已经改变了。同样的论证也适用于我的4个以上参数
这都是关于代码注入,而不是实例构造。注入类型 对于如何将依赖项注入bean,有三个选项:
@Autowired
时发生的情况
注射指南 一般指南(见或部分)如下:
- 对于强制依赖项或以不可变为目标时,请使用构造函数注入
- 对于可选或可更改的依赖项,请使用setter注入
- 在大多数情况下避免现场注入
现场注入缺陷 不赞成现场注入的原因如下:
- 不能像构造函数注入那样创建不可变对象
- 类与DI容器紧密耦合,不能在DI容器之外使用
- 您的类不能在没有反射的情况下实例化(例如在单元测试中)。您需要DI容器来实例化它们,这使您的测试更像是集成测试
- 您真正的依赖项是从外部隐藏的,不会反映在接口中(构造函数或方法)
- 有十个依赖项真的很容易。如果您使用的是构造函数注入,那么您将拥有一个包含十个参数的构造函数,这将表明有可疑之处。但您可以使用字段注入无限期地添加注入字段。拥有太多的依赖项是一个危险信号,表明类通常做不止一件事,并且它可能违反单一责任原则
结论 根据您的需要,您应该主要使用构造函数注入或构造函数和setter注入的混合。现场注入有许多缺点,应该避免。场注入的唯一优点是更方便地写入,但这并不超过所有缺点
进一步阅读
我写了一篇关于为什么通常不推荐现场注入的博客文章:。这是软件开发中永无止境的讨论之一,但业界的主要影响者对这个话题越来越固执己见,并开始建议构造函数注入作为更好的选择 构造函数注入 优点:
- 更好的可测试性。单元测试中不需要任何模拟库或Spring上下文。您可以创建要使用新关键字测试的对象。这样的测试总是更快,因为它们不依赖于反射机制。(30分钟后被问到。如果作者使用了构造函数注入,它就不会出现)
- 不变性。一旦设置了依赖项,就无法更改它们
- 更安全的代码。在执行构造函数之后,您的对象就可以使用了,因为您可以验证作为参数传递的任何内容。对象可以是就绪的,也可以不是就绪的,两者之间没有状态。通过场注入,当对象脆弱时,引入中间步骤李>
- 强制依赖关系的清晰表达。在这个问题上,现场注入是不明确的
- 让开发人员思考设计。dit写了一个有8个参数的构造函数,这实际上是一个糟糕的设计和性能的标志。不管一个类在其构造函数或字段中是否有8个依赖项,它总是错误的。与通过字段相比,人们更不愿意向构造函数添加更多依赖项。它作为一个信号传递给你的大脑
@Component public class MyComponent { private final Cart cart; @Autowired public MyComponent(Cart cart){ this.cart = cart; } }