Java Google Guice 与 JSR-299 CDI / Weld

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2652126/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 10:22:16  来源:igfitidea点击:

Google Guice vs. JSR-299 CDI / Weld

javadependency-injectionaopcdijboss-weld

提问by deamon

Weld, the JSR-299 Contexts and Dependency Injection reference implementation, considers itself as a kind of successor of Spring and Guice.

Weld,JSR-299 Contexts and Dependency Injection 参考实现,认为自己是 Spring 和 Guice 的继承者。

CDI was influenced by a number of existing Java frameworks, including Seam, Guice and Spring. However, CDI has its own, very distinct, character: more typesafe than Seam, more stateful and less XML-centric than Spring, more web and enterprise-application capable than Guice. But it couldn't have been any of these without inspiration from the frameworks mentioned and lots of collaboration and hard work by the JSR-299 Expert Group (EG).

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

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

What makes Weld more capable for enterprise application compared to Guice? Are there any advantages or disadvantages compared to Guice? What do you think about Guice AOP compared to Weld interceptors? What about performance?

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

My choice

我的选择

In the end I decided to use Guice because I like the clean programming model which comes almost without annotations besides @Inject by default. It is much easier to use external libs with Guice than with CDI. AOP is also pretty simple with Guice.

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

回答by Bozho

CDI (Weld) hasn't yet been used widely, so a comparison is hard to make. A few points:

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

  • CDI has been designed with integration with EJB3, JSF and other JavaEE standards in mind. CDI has the so called portable extensions which allow third-party libraries to integrate with the lifecycle and internal functioning of a CDI implementation
  • CDI has been designed with all possible corner-cases in mind so it is likely that it covers everything you need. Spring, Guice and Seam evolved to such a state, while CDI uses the experience from these three.
  • in my opinion, CDI interceptors will not be able to meet all the demands that Spring AOP has met. Perhaps the same goes for Guice AOP. You can't define an interceptor using AspectJ syntax.
  • the lack of xml definitions is both an advantage and a disadvantage and some people (rightly in some cases) prefer xml configuration.
  • the extended use of qualifier annotations will (in my opinion) generate some big messes if not used carefully.
  • CDI 的设计考虑到了与 EJB3、JSF 和其他 JavaEE 标准的集成。CDI 具有所谓的可移植扩展,允许第三方库与 CDI 实现的生命周期和内部功能集成
  • CDI 的设计考虑了所有可能的极端情况,因此它很可能涵盖您需要的一切。Spring、Guice和Seam进化到了这样的状态,而CDI则借鉴了这三者的经验。
  • 在我看来,CDI 拦截器将无法满足 Spring AOP 已经满足的所有需求。也许Guice AOP 也是如此。您不能使用 AspectJ 语法定义拦截器。
  • 缺少 xml 定义既是优点也是缺点,有些人(在某些情况下是正确的)更喜欢 xml 配置。
  • 如果不小心使用,限定符注释的扩展使用(在我看来)会产生一些大混乱。

回答by Kariem

Before trying to answer your question, let me just add an important piece of information: JSR 330(@Inject) was standardized by Guice and Spring projects (announcement from May 2009) and is being reused in JSR 299. This covers basic DI mechanisms in terms of declaring an injection point.

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

Now, back to the question - with the disclaimer that I have far more experience with Spring than with Guice.

现在,回到问题 - 免责声明,我在 Spring 方面的经验远多于 Guice。

Enterprise capabilities in Weld

Weld 中的企业能力

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

Advantages / Disadvantages

优点缺点

Note: I will try to add a few items here later, but this answer is already longer than I had expected, sorry.

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

  • Weld/CDI

    • Standardization: If something is standardized and there is a good implementation, a lot of people will be using it. Example: Built-in scopesin Weld provide a few more scopes than Guiceor Spring. All of these can be extended, but application frameworks will rather rely on standard scopes if they are being used by a large community.
    • Container support: this is similar to the previous item, but a major argument for adoption. Major open source application servers, such as Glassfish and JBoss 6 provide CDI support (see here).
  • Guice/Spring

    • Actual application: Most of the existing applications will be using Guice/Spring already. Spring/Guice have always built on standards and provided new capabilities where no standards existed or could not be used. If you follow with the respective best-practices, the framework will help you make your application standards-based and clean.
  • 焊接/CDI

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

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

AOP and Interceptors

AOP 和拦截器

This is a very heavily discussed topic, and I cannot favor one over the other. Both mechanisms are very powerful but require at least a minimum understanding of the application's architecture. Also have look at Decoratorsand the previously referenced Events. It is best to go with the right tool, but don't forget that if a developer has to work with one of these mechanisms it is a good thing if he/she understands the concept.

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

Performance

表现

Unfortunately I could not look into this yet, but there are a few rules I try to follow, especially when using a framework that gives you a lot of functionality without you noticing it:

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

  • Whenever possible, prefer a single wiring step over multiple lookups at runtime.
  • If possible, do all the wiring on application initialization.
  • Any interception step or AOP proxy adds a few method calls to the stack.
  • 在可能的情况下,在运行时更喜欢单个接线步骤而不是多次查找。
  • 如果可能,请在应用程序初始化时完成所有接线。
  • 任何拦截步骤或 AOP 代理都会向堆栈添加一些方法调用。

回答by Jan

Another differentiator is that CDI is very Java EE oriented. It provides a mechanism to gluethe different Java EE subsystemstogether.

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

Ie. By annotating a bean with @Named("book"), the bean becomes known in the unified EL (Expression Language) as 'book'.

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

Then you can use it in a JSF page for instance:

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

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

回答by Thorbj?rn Ravn Andersen

The most important feature CDI has opposed to Guice, is that it is a standardpart of Java EE 6.

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

The importance of this cannot be underestimated, as it means that CDI is the DI-standard you should use when coding web applications.

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

A while back I had a look at the technologies to be able to determine how we could have a standard core distribution - suitably prepared - where we could add extra modules at will which could override existing functionality without having to change the core modules. I.e. add an extra jar, and the functionality activates automatically.

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

It turned out that the best way for us to do this for a code base used in both desktop and web applications, was to use JSR-330 annotations for our code, and then use either CDI or Guice (SVN, coming real soon now in 3.0) as the engine.

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

After a few projects I've found that I like the Guice configuration best instead of the opaque magic happening in Weld. Additionally I found that the way to do what we want as described above with Weld, I have to mark the class in the extra jar as @Alternative, and then mention in beans.xml that I want the alternative class enforced (and that is not robust against refactoring).

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

But, all in all, JSR-330 allows us to do something which was very tedious and fragile before (because newbinds so extremely tightly), and that is a great win. I can strongly recommend looking into DI if you have any need like this.

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

回答by deamon

CDI for Guice usersis a nice comparison.

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

回答by beni_koch

I have used Guice in an AWS Lambda serverless application. AWS recommends using Guice or Dagger over Spring in a Lambda function. See AWS Lambda best practices

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

The primary reason is that Guice and Dagger are smaller frameworks and have faster start up time, which is essential in Lambda.

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

Although the OP hasn't mentioned Spring, both Spring and CDI/weld are meant for enterprise level applications, which often require additional features that these frameworks provide. Hence for smaller applications, which only require DI, Guice or Dagger would be optimal.

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