当前位置: 首页 > 面试题库 >

为什么在Java EE中使用CDI

商风华
2023-03-14
问题内容

我知道有很多文章可以解释如何在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 in Practice,
以一个AccountService类的示例为例,而该类又使用的实例AccountDao。对于长报价我深表歉意,但我认为这确实使为什么注入的资源能够提供一些超出标准初始化的东西很重要。

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

此外,您可以在外部创建依赖项,并通过setter方法或构造函数参数在AccountService上进行设置。
这样做将消除硬的内部依赖关系(只要它们在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之后,您的程序现在可以AccountService从Spring ApplicationContext
请求的实例,并且Spring DI框架将在实例化之后进行所有需要实例化的工作。


问题答案:

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

像Spring这样的依赖注入引擎比您的工厂做得多。要复制它们提供的所有内容,将需要多个工厂类和一行代码。

当然,您不必使用它。您始终可以自由发明自己的车轮。而且,您应该-
如果您的目的是学习如何制作轮子或消除依赖关系。

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

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

“还不清楚什么是更多”

这里有一些优点:

  1. 松耦合
  2. 更容易的测试
  3. 更好的分层
  4. 基于界面的设计
  5. 动态代理(针对AOP)。


 类似资料:
  • 问题内容: 我不仅想知道什么是Facet,还想知道什么是Facet’在物理层面上’(据我了解,它不是一个单独的jar,而是什么?)? 我还想知道它在部署后如何影响我的应用程序。我将以实际示例进行说明: 我有两个方面(由IDE创建):Spring Facet和Web Facet(用于jsf)。我将其部署到Tomcat,并且我的应用程序运行良好。 然后,我(通过IDE)又添加了一个方面-JPA Fac

  • 我正在使用以下源代码目录结构的JavaEE Web应用程序: 我感兴趣的文件夹是:它包含、用于设置servlet的xml文件、SpringBean连接上下文以及JSP标记和视图。我试图理解是什么限制/定义了这种结构。例如,JSP文件是否总是必须在中,或者它们可能在其他地方?在WEB-INF中是否还有其他内容?维基百科的WAR文件条目提到了Java类的,JAR文件的——我不确定除了其他源文件位置之外

  • 问题内容: 我已经使用Maven原型()创建了一个新的Java EE 6项目,但是不明白为什么某些东西放在POM元素中。具体来说,我不明白为什么将“” 复制到认可目录。根据对这个问题的回答,这是编译所必需的,但是当我删除下的相关元素时,我的项目可以正常编译。 由于已在POM中作为依赖项提供,因此不能将其用于编译吗? 问题答案: 它应该编译,因为对此工件也有依赖性: Maven手册页中 提供的 描述

  • 问题内容: 我正在查看一个串行程序,观察到它们在使用之前先使用过。为什么这是必需的。为什么我们不能直接致电并检查是否失败?另外,为什么要在我已经将文件描述符设置为传递时将文件描述符增加1并传递它呢? 例: fds已经具有fd的值 问题答案: 该系统调用告诉你是否有任何数据的文件描述符你感兴趣的。严格来说,它是文件描述符的读操作是否会阻止或不是一个问题读取。 如果您在文件描述符(例如连接到串行端口的

  • 问题内容: Java不能执行运算符重载,但可以用于和和其他一些类。这怎么可能? 更新: 为什么这样做? 问题答案: 不是操作员重载的示例。在语言中被内置为合并运算符 和 算术加法运算符。 这意味着用Java编写程序的人不能重载运算符,但是就Java语言的语法而言,它被定义为连接和加法运算符。 编辑 它适用于其他类,如和由于自动装箱。 如果您看一下执行字符串连接的Java程序的字节码,您会发现它创建

  • 问题内容: 我只是想知道为什么在类的方法中使用质数?例如,当使用生成我的方法时,总是使用素数31: 问题答案: 因为您想要乘以的数量以及要插入的存储桶的数量具有正交素数分解。 假设要插入8个桶。如果您要用来乘以的数字是8的倍数,则插入的存储桶将仅由最低有效项(一个根本没有相乘)确定。类似的条目将发生冲突。不适用于哈希函数。 31是一个足够大的素数,因此不可能被它整除(实际上,现代的Java Has