Google Guice vs. JSR-299 CDI / Weld

时间:2010-04-16 10:22:38

标签: java dependency-injection aop cdi jboss-weld

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。

6 个答案:

答案 0 :(得分:53)

在尝试回答您的问题之前,我先添加一条重要信息:JSR 330@Inject)由Guice和Spring项目(announcement from May 2009)标准化,并且正在{ {3}}。这包括在声明注入点方面的基本DI机制。

现在,回到这个问题 - 免责声明我对Spring的经验远远超过Guice。

Weld中的企业功能

优点/缺点

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

  • <强>焊接/ CDI

    • 标准化:如果标准化并且有很好的实施,很多人都会使用它。示例:Weld中的Portable extensions提供的范围比Built-in scopesGuice多一些。所有这些都可以扩展,但如果大型社区使用标准范围,应用程序框架将依赖于标准范围。
    • 容器支持:这与前一项类似,但是采用的一个主要论据。主要的开源应用服务器,如Glassfish和JBoss 6,提供CDI支持(见Spring)。
  • <强>吉斯/弹簧

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

AOP和拦截器

这是一个讨论很多的话题,我不能赞成其中一个。这两种机制都非常强大,但至少需要了解应用程序的体系结构。另请查看here和之前引用的Decorators。最好使用正确的工具,但不要忘记,如果开发人员必须使用其中一种机制,那么如果他/她理解这个概念就是一件好事。

<强>性能

不幸的是我还没有看到这个,但是我尝试遵循一些规则,特别是在使用一个框架时,如果你没注意到它就会提供很多功能:

  • 只要有可能,在运行时更喜欢单个布线步骤而不是多个查找。
  • 如果可能,请在应用程序初始化时进行所有接线。
  • 任何拦截步骤或AOP代理都会向堆栈添加一些方法调用。

答案 1 :(得分:19)

CDI(Weld)尚未被广泛使用,因此难以进行比较。几点:

  • CDI的设计考虑了与EJB3,JSF和其他JavaEE标准的集成。 CDI具有所谓的可移植扩展,允许第三方库与CDI实现的生命周期和内部功能集成。
  • CDI的设计考虑了所有可能的角落情况,因此很可能涵盖了您需要的所有内容。 Spring,Guice和Seam演变成这样的状态,而CDI则使用这三种体验。
  • 在我看来,CDI拦截器将无法满足Spring AOP遇到的所有要求。也许Guice AOP也是如此。您无法使用AspectJ语法定义拦截器。
  • 缺少xml定义既有利也有缺点,有些人(在某些情况下正确)更喜欢xml配置。
  • 如果不仔细使用,限定词注释的扩展使用(在我看来)会产生一些大的混乱。

答案 2 :(得分:9)

CDI for Guice users是一个很好的比较。

答案 3 :(得分: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。

答案 4 :(得分:5)

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

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

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

    <h:outputLabel value="Book title:" for="bookTitle"/>
    <h:outputText id="bookTile" value="#{book.title}"/>

答案 5 :(得分:2)

我已在无AWS Lambda服务器应用程序中使用Guice。 AWS建议在Lambda函数中在Spring上使用Guice或Dagger。参见AWS Lambda best practices

主要原因是Guice和Dagger是较小的框架,并且启动时间更快,这在Lambda中至关重要。

尽管OP并未提及Spring,但Spring和CDI / weld均适用于企业级应用程序,这些应用程序通常需要这些框架提供的其他功能。因此,对于只需要DI的小型应用程序,Guice或Dagger是最佳选择。