61

Weld 是 JSR-299 上下文和依赖注入参考实现,它认为自己是 Spring 和 Guice 的一种继承者。

CDI 受到许多现有 Java 框架的影响,包括 Seam、Guice 和 Spring。然而,CDI 有它自己非常独特的特点:比 Seam 更类型安全,比 Spring 更有状态且更少以 XML 为中心,比 Guice 更有 Web 和企业应用程序能力。但是,如果没有上述框架的启发以及 JSR-299 专家组 (EG) 的大量协作和辛勤工作,就不可能有这些。

http://docs.jboss.org/weld/reference/latest/en-US/html/1.html

与 Guice 相比,是什么让 Weld 更适合企业应用?与Guice相比有什么优点或缺点吗?与 Weld 拦截器相比,您如何看待 Guice AOP?性能呢?

我的选择

最后我决定使用 Guice,因为我喜欢干净的编程模型,它默认除了 @Inject 之外几乎没有注释。在 Guice 中使用外部库比使用 CDI 容易得多。Guice 的 AOP 也非常简单。

4

6 回答 6

53

在尝试回答您的问题之前,让我先添加一条重要信息:JSR 330 ( @Inject) 已被 Guice 和 Spring 项目标准化(从 2009 年 5 月发布)并在 JSR 299中被重用。这涵盖了声明注入点方面的基本 DI 机制。

现在,回到这个问题——我在 Spring 方面的经验比在 Guice 方面的经验要多得多。

Weld 中的企业能力

  • 替代配置机制在 JSR-299 中具有非常简洁的设计,并允许在 Java 代码之外使用配置机制 ( beans.xml)。
  • 事件是一个非常强大的东西,非常适合 JMS。我刚刚为 Guice 找到了一个 Event Bus,但我不能说它是如何比较的。
  • 可移植扩展是一种 SPI,可用于与现有技术集成或以干净的方式包装遗留代码。

优点缺点

注意:我稍后会尝试在这里添加一些项目,但是这个答案已经比我预期的要长,抱歉。

  • 焊接/CDI

    • 标准化:如果某些东西是标准化的并且有很好的实现,很多人都会使用它。示例: Weld 中的内置范围提供了比GuiceSpring更多的范围。所有这些都可以扩展,但如果应用程序框架被大型社区使用,它们将宁愿依赖标准范围。
    • 容器支持:这与上一项类似,但它是采用的主要论据。主要的开源应用程序服务器,例如 Glassfish 和 JBoss 6 提供 CDI 支持(参见此处)。
  • 古斯/春天

    • 实际应用程序:大多数现有应用程序已经在使用 Guice/Spring。Spring/Guice 始终建立在标准之上,并在不存在或无法使用标准的情况下提供新功能。如果您遵循各自的最佳实践,该框架将帮助您使您的应用程序基于标准且干净。

AOP 和拦截器

这是一个讨论得非常热烈的话题,我不能偏袒一个。这两种机制都非常强大,但至少需要对应用程序架构有最低限度的了解。还可以查看装饰器和之前引用的事件。最好使用正确的工具,但不要忘记,如果开发人员必须使用其中一种机制,那么他/她理解这个概念是一件好事。

表现

不幸的是,我还不能对此进行研究,但是我尝试遵循一些规则,尤其是在使用一个为您提供很多功能而您却没有注意到它的框架时:

  • 只要有可能,最好在运行时使用单个连线步骤而不是多个查找。
  • 如果可能,请在应用程序初始化时完成所有接线。
  • 任何拦截步骤或 AOP 代理都会向堆栈添加一些方法调用。
于 2010-05-11T13:45:46.030 回答
20

CDI(焊接)尚未广泛使用,因此很难进行比较。几点:

  • CDI 的设计考虑了与 EJB3、JSF 和其他 JavaEE 标准的集成。CDI 具有所谓的可移植扩展,允许第三方库与 CDI 实现的生命周期和内部功能集成
  • CDI 的设计考虑了所有可能的极端情况,因此它很可能涵盖了您需要的所有内容。Spring、Guice 和 Seam 进化到了这样的状态,而 CDI 则利用了这三者的经验。
  • 在我看来,CDI 拦截器将无法满足 Spring AOP 已经满足的所有需求。Guice AOP 可能也是如此。您不能使用 AspectJ 语法定义拦截器。
  • 缺少 xml 定义既是优点也是缺点,有些人(在某些情况下是正确的)更喜欢 xml 配置。
  • 如果不小心使用,限定符注释的扩展使用(在我看来)会产生一些大混乱。
于 2010-04-16T11:04:31.523 回答
10

Guice 用户的 CDI是一个很好的比较。

于 2013-10-29T13:18:26.133 回答
8

CDI 反对 Guice 的最重要的特性是它是 Java EE 6 的标准部分。

这一点的重要性不容小觑,因为这意味着 CDI 是您在编写 Web 应用程序时应该使用的 DI 标准。

不久前,我研究了能够确定我们如何拥有标准核心发行版的技术 - 适当准备 - 我们可以随意添加额外的模块,这些模块可以覆盖现有功能而无需更改核心模块。即添加一个额外的jar,该功能会自动激活。

事实证明,对我们在桌面和 Web 应用程序中使用的代码库执行此操作的最佳方法是对我们的代码使用 JSR-330 注释,然后使用 CDI 或 Guice(SVN,现在即将推出) 3.0) 作为引擎。

经过几个项目后,我发现我最喜欢 Guice 配置,而不是 Weld 中发生的不透明魔法。此外,我发现使用 Weld 执行上述我们想要的方法,我必须将额外 jar 中的类标记为 @Alternative,然后在 beans.xml 中提到我希望强制执行替代类(这不是对重构具有鲁棒性)。

但是,总而言之,JSR-330 允许我们做一些以前非常乏味和脆弱的事情(因为new绑定非常紧密),这是一个巨大的胜利。如果您有这样的需求,我强烈建议您研究 DI。

于 2010-12-20T19:02:54.467 回答
5

另一个区别是 CDI 非常面向 Java EE。它提供了一种将不同的Java EE 子系统粘合在一起的机制。

IE。通过用 注释 bean @Named("book"),bean 在统一的 EL(表达式语言)中被称为 ' book'。

然后您可以在 JSF 页面中使用它,例如:

    <h:outputLabel value="Book title:" for="bookTitle"/>
    <h:outputText id="bookTile" value="#{book.title}"/>
于 2010-11-05T12:20:57.913 回答
3

我在 AWS Lambda 无服务器应用程序中使用了 Guice。AWS 建议在 Lambda 函数中使用 Guice 或 Dagger 而不是 Spring。请参阅AWS Lambda 最佳实践

主要原因是 Guice 和 Dagger 是更小的框架,启动时间更快,这在 Lambda 中是必不可少的。

尽管 OP 没有提到 Spring,但 Spring 和 CDI/weld 都适用于企业级应用程序,这通常需要这些框架提供的附加功能。因此,对于只需要 DI 的较小应用程序,Guice 或 Dagger 将是最佳选择。

于 2018-10-23T06:18:05.853 回答