繁体   English   中英

Google Guice vs. JSR-299 CDI / Weld

[英]Google Guice vs. JSR-299 CDI / 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也很简单。

在尝试回答您的问题之前,让我添加一条重要的信息: 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代理都会向堆栈添加一些方法调用。

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

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

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

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。

另一个区别是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}"/>

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

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM