java - 为什么在 Java EE 中使用 CDI

标签 java spring jakarta-ee cdi

我知道有很多文章解释如何在 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,现在这变得更有意义了。下面的段落摘自 Spring 实践,以 AccountService 类为例,该类又使用 AccountDao 的实例。我对冗长的引用表示歉意,但我认为它确实触及了为什么注入(inject)的资源提供了超出标准初始化的东西的核心。

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

此外,您可以在外部创建依赖项,并通过 setter 方法或构造函数参数在 AccountService 上设置它们。这样做会消除硬的内部依赖关系(只要它们是通过接口(interface)在 AccountService 中声明的),但你会到处都有重复的初始化代码。以下是创建 DAO 并连接它的方法 以 Spring 方式决定您的 AccountService:

<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 请求 AccountService 实例,Spring DI 框架将负责实例化所有需要实例化的内容。

最佳答案

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

像Spring这样的依赖注入(inject)引擎,比你的工厂做的事情要多得多。复制它们提供的所有功能将需要多个工厂类和一行代码。

当然你不必使用它。你总是可以自由地发明自己的轮子。你应该 - if your purpose is to learn how to make wheels或消除依赖性。

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

seminal article关于依赖注入(inject)是由 Martin Fowler 编写的。我建议阅读它;八年后仍然很棒。

"still not clear on what the more is"

以下是一些优点:

  1. 松散耦合
  2. 更容易测试
  3. 更好的层次感
  4. 基于界面的设计
  5. 动态代理(继续到 AOP)。

关于java - 为什么在 Java EE 中使用 CDI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23869755/

相关文章:

java - 如何在 Jsp 中屏蔽文本字段中的几个字符

java - 对密码编码器的服务层进行封装

java - Hibernate 不驱逐查询缓存(不可重复读取问题)

java - RMI、EJB 和回调

java - Spring mongodb 统计集合中的所有文档

java - 没有基础表的 JPA 实体

java - 获取对象的大小

java - 我在一个运行良好的 EJB3 项目中收到 404 错误

java - 4 字节 UTF-8 序列的字节 2 无效,但仅在执行 JAR 时?

java - 无法从 eclipse 运行 spring 项目,ClassNotFoundException : org. springframework.web.context.ContextLoaderListener