我知道有很多文章解释如何在 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"
以下是一些优点:
- 松散耦合
- 更容易测试
- 更好的层次感
- 基于界面的设计
- 动态代理(继续到 AOP)。
关于java - 为什么在 Java EE 中使用 CDI,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23869755/