CDI 是 Spring 的一个很好的替代品吗? [关闭]

Posted

技术标签:

【中文标题】CDI 是 Spring 的一个很好的替代品吗? [关闭]【英文标题】:Is CDI a good replacement of Spring? [closed] 【发布时间】:2011-08-23 19:42:44 【问题描述】:

我们计划从头开始编写一个 Web 应用程序,已决定使用符合 Java EE 6 标准的最新版 Glassfish,因此我们正在分析是否可以使用 CDI 来代替 Spring。

我们可以说 CDI 可以替代 Spring 吗?

【问题讨论】:

另见dzone.com/articles/cdi-10-vs-spring-31-feature 【参考方案1】:

2021 年更新:我回答最初的问题已经 10 年了,但我仍然偶尔获得支持。我能否请未来的读者接受我的回答:2011 年 Java 企业版图的反映。

CDI 代表“上下文和依赖注入”,而 Spring 是一个围绕依赖注入容器的完整生态系统。要比较两者,您必须区分比较。

依赖注入由两个容器处理。主要区别在于 CDI 以 动态(又名:有状态)方式处理 DI - 这意味着在执行时解决依赖关系。 Spring 的方法是静态 - 这意味着组件在创建时 连接在一起。虽然 CDI 方式乍一看可能有点不寻常,但它要优越得多,并提供更多和高级的选项(我写这篇文章的背景是两个高效的 CDI 应用程序)。

如果您查看生态系统,情况就不同了:Spring 捆绑了很多 jar (>150),而 CDI 本身非常小。典型的 CDI 用法是在 Java EE 6 应用程序服务器内部,但您可以轻松地使其在 servlet 引擎甚至 Java SE 中工作。这意味着使用 CDI 不会假设使用 Hibernate、JPA、EJB 或其他任何东西 - 这取决于您。

如果您需要更多功能,CDI 带有 可移植扩展 的概念(这本身就使 API 变得有价值)。存在独立的扩展模块,如 Apache CODI 和 Seam 3,涵盖安全、邮件、报告等主题。

总结一下:CDI 并不是 Spring 生态系统的“替代品”,而是对 Spring 的依赖注入机制的改进。它是 Java EE 6 的一部分,因此如果您使用 Java EE 6 的 GlasFish,那么您绝对应该选择 CDI。在我看来,您的问题是:我可以用 Java EE 6 替换 Spring 吗?我想我的答案很明显;-)

查看Weld 以获得良好的开端...

【讨论】:

我认为 CDI 使用像 Spring 一样的静态注入。根据Weld documentationThe @Inject annotation lets us define an injection point that is injected during bean instantiation.,据我了解,动态注入是多次发生的注入。每次在该组件上调用业务方法时都会发生这种情况。同样对我来说,stateful way inyection 意味着能够处理来自不同上下文的 bean 注入,它使用引用每个 bean 的“正确”实例的代理 不,这是不正确的——我不遵循你对动态注入的定义。 CDI 的动态部分是代理依赖项(如您所写),并且代理将在请求时注意解析正确的依赖项(因此依赖项的两次调用可能会转发到该依赖项的两个不同实例)。但也许评论不是开始讨论的正确位置,您可能想为此打开一个新问题... 现在还是这样吗? Spring's approach is static。我认为这并不完全准确(至少目前如此)。 Spring 还提供了其他作用域(例如prototype 作用域),它在请求执行期间在运行时解析bean 和wire。【参考方案2】:

Spring 不仅仅是一个依赖注入容器。它还具有 AOP 工具、用于 JPA、SQL 等的模板,甚至更多。

但是 CDI 可以用作 Spring 的 DI API 的替代品。

【讨论】:

我认为 CDI 通过拦截器处理 AOP 拦截器与一般的 AOP 非常相似,但它们没有 AOP 框架或 AspectJ 之类的语言提供的广泛功能。 您可以编写扩展,根据您的规则向 bean 添加拦截器。这很容易。对于大多数应用程序而言,AOP 的广泛使用过于复杂而无用。 所有可以通过 AOP 实现的东西都可以通过 CDI 拦截器来实现。请考虑不要写宗教答案。【参考方案3】:

我使用Apache OpenWebBeans 作为 CDI 实现,并使用 MyFaces CODI 作为几个项目的可移植扩展。我对此感到非常满意,并且对此没有任何问题。 OpenWebBeans 目前在文档方面缺乏一点,但如果你不能让某些东西工作,那么使用 MyFaces 提供的 Maven Archetypes 来生成具有所有需要的依赖项的简单项目或者你在邮件列表中询问是很容易的。如果您只是在您的应用程序上工作并且不会被讨厌的错误阻止,那就太好了。我还用 Spring 做了很多项目。没关系,但如果你问我下一个项目会使用什么,那么明确的答案是 OpenWebBeans 和 CODI!我更喜欢 OpenWebBeans 而不是 Weld,因为 OpenWebBeans 非常易于采用,这很棒,因为您可以或多或少地自定义官方 CDI API/SPI 未涵盖的所有内容,并且运行时性能更好。在第一个项目之后,我再也不会质疑 CODI,因为它非常稳定,他们有定期发布,其中大多数都带来了很好的新功能,从而大大提高了生产力。恕我直言,CODI 是整个 CDI 领域中最稳定和最创新的地方。

回答您的问题: 对我来说,CDI 完全取代了 Spring,但您需要可移植的扩展来填补空白。作为标准的 CDI 从未打算解决所有问题,并且某些部分(例如对话)被设计破坏了。好消息是你有像 MyFaces CODI 这样的伟大项目。 CODI 几乎解决了所有这些问题。

【讨论】:

以上是关于CDI 是 Spring 的一个很好的替代品吗? [关闭]的主要内容,如果未能解决你的问题,请参考以下文章

Firebase + Batch 在推送通知方面是 Parse 的一个很好的替代品吗?

复制 /var/lib/mysql 目录是 mysqldump 的一个很好的替代方案吗?

复制 /var/lib/mysql 目录是 mysqldump 的一个很好的替代方案吗?

空别名 shared_ptr 是无操作删除 shared_ptr 的一个很好的替代方案吗?

JSP for Spring MVC视图层的替代方案

CDI 中的 Spring-JDBC 等价物是啥?