为什么在 Java EE 中使用 CDI

2022-08-31 20:17:10

我知道有很多文章解释了如何在Java EE中使用CDI,但我很难弄清楚这实际上带来了什么优势。例如,假设我有一个当前使用 Foo 实例的类。我可能会做

Foo myFoo = new Foo();

// Better, FooFactory might return a mock object for testing    
Foo myFoo = FooFactory.getFoo();

我一直在阅读CDI,我可以做到:

@Inject
Foo myFoo;

但是为什么这比以前基于工厂的方法更好?我假设还有其他一些我不知道的用例,但我无法识别这一点。

如果我理解了下面的响应,那么概念是 DI 框架充当集中配置的主对象工厂。这是一个合理的解释吗?

更新

从那以后,我开始学习春天,现在这更有意义了。下面的段落取自 Spring in Practice,以一个类为例,该类又使用 .我很抱歉这个长引号,但我认为它确实触及了为什么注入的资源提供了一些超过标准初始化的东西的核心。AccountServiceAccountDao

您可以使用 new 关键字构造帐户服务,但服务层对象的创建很少如此简单。它们通常依赖于 DAO、邮件发件人、SOAP 代理等等。您可以在 AccountService 构造函数中以编程方式实例化每个依赖项(或通过静态初始化),但这会导致硬依赖项和级联更改在换出时。

此外,还可以在外部创建依赖项,并通过 setter 方法或构造函数参数在 AccountService 上设置它们。这样做可以消除硬的内部依赖关系(只要它们是通过接口在帐户服务中声明的),但是您将在任何地方重复初始化代码。以下是如何创建 DAO 并将其连接到您的帐户服务:

<bean id="accountDao" class="com.springinpractice.ch01.dao.jdbc.JdbcAccountDao"/>

<bean id="accountService"
    class="com.springinpractice.ch01.service.AccountService">
    <property name="accountDao" ref="accountDao"/>
</bean>

如上所述配置了bean之后,您的程序现在可以从Spring ApplicationContext请求一个实例,Spring DI框架将负责实例化需要实例化的所有内容。AccountService


答案 1

编写CDI的人给了你一个大对象工厂;他们为你做了工作,比你更好。它是 XML 配置或注释驱动的,因此您不必在代码中嵌入所有内容。

依赖注入引擎,如Spring,比你的工厂做得更多。需要多个工厂类和一行代码来复制它们提供的所有内容。

当然,您不必使用它。你总是可以自由地发明自己的轮子。你应该 - 如果你的目的是学习如何制造轮子或消除依赖性。

但是,如果您只想开发应用程序,则最好使用其他人提供的工具,当他们为您提供优势时。

关于依赖注入的开创性文章由Martin Fowler撰写。我建议阅读它;八年后,它仍然很棒。

“仍然不清楚什么是更多”

以下是一些优点:

  1. 更松的耦合
  2. 测试更简单
  3. 更好的分层
  4. 基于接口的设计
  5. 动态代理(从 AOP 开始)。

答案 2

使用依赖注入的目的是使使用注入的东西的代码不依赖于工厂。在工厂代码示例中,代码中嵌入了一个静态方法调用,DI 方法不需要该调用。

正在注入的东西不应该知道工厂。工厂对 DI 中没有的测试选项进行了限制。具体来说,如果你有一个具有 Foo 的 Bar 对象,那么对该 Bar 对象的测试可以直接创建一个 Foo 或模拟 Foo 并将其放在 Bar 上,而无需涉及 FooFactory,并且您不必编写 FooFactory,它是不执行任何实现应用程序业务逻辑的样板。myFoo


推荐