Google Guice与PicoContainer进行依赖注入


100

我的团队正在研究依赖项注入框架,并试图在使用Google-Guice和PicoContainer之间做出选择。

我们正在寻找框架中的几件事情:

  1. 较小的代码占用空间-我所说的较小的代码占用空间是我们不想在我们的代码库中到处都有依赖项注入代码垃圾。如果需要在将来进行重构,我们希望它尽可能简单。
  2. 性能-创建和注入对象时,每个框架有多少开销?
  3. 易于使用-学习曲线是否很大?我们是否必须编写大量代码才能使某些简单工作起作用?我们希望配置尽可能少。
  4. 社区规模-较大的社区通常意味着将继续维护项目。我们不想使用框架,而不得不修复我们自己的错误;)此外,框架的开发人员/用户社区也可以(希望)回答我们所遇到的任何问题。

将两个框架与所列标准进行比较将不胜感激。任何有助于将两者进行比较的个人经验也将非常有帮助。

免责声明:我对依赖注入还很陌生,因此如果我提出的问题与本次讨论无关,请原谅我。


更新:您可能还想考虑CDI 2.0 – Java上下文和依赖注入。从2017-04开始在JSR 365中标准化。
罗勒·布尔克

Answers:


115

您可能希望将Spring纳入您正在考虑的Dependency Injection框架列表中。以下是您问题的一些答案:

耦合到框架

Pico -Pico往往会阻止二传手的注入,但除此之外,您的课程无需了解Pico。只是需要知道的接线(对于所有DI框架都是正确的)。

Guice -Guice现在支持标准的JSR 330注释,因此您不再需要代码中特定于Guice的注释。Spring还支持这些标准注释。Guice伙计们使用的论据是,如果不运行Guice批注处理器,那么如果您决定使用其他框架,则它们不会产生影响。

Spring -Spring的目的是让您避免在代码中提及Spring框架。因为他们确实有很多其他的帮助器/实用程序等,但是依赖于Spring代码的诱惑非常强烈。

性能

Pico-我对Pico的速度特性不太熟悉

Guice -Guice设计得很快,参考文献中提到的比较有一些数字。当然,如果速度是主要考虑因素,则应考虑使用Guice或手工接线

春天 -春天会很慢。已经进行了一些工作来使其更快,并且使用JavaConfig库应该可以加快速度。

使用方便

Pico-易于配置。Pico可以为您做出一些自动接线决定。尚不清楚它如何扩展到非常大的项目。

Guice-配置简单,您只需添加批注并继承自AbstractModule即可将事物绑定在一起。由于将配置保持在最低水平,因此可以很好地适应大型项目。

Spring-相对容易配置,但是大多数示例使用Spring XML作为配置方法。随着时间的推移,Spring XML文件可能会变得非常庞大和复杂,并且需要花费一些时间来加载。考虑混合使用Spring和手动启动的依赖项注入来克服此问题。

社区规模

笔克 -小

Guice-

春天 -大

经验

Pico-我在Pico上没有太多经验,但是它不是一个广泛使用的框架,因此很难找到资源。

Guice -Guice是一个流行的框架,当您有一个要重新开始大量开发工作的大型项目时,欢迎关注速度。我担心配置的分布式性质,即不容易看到整个应用程序如何组合在一起。在这方面有点像AOP。

春季 -春季通常是我的默认选择。就是说,XML可能变得很繁琐,并且导致速度变慢。我经常最终将手工制作的依赖注入和Spring结合使用。当您实际上需要基于XML的配置时,Spring XML相当不错。Spring还付出了很多努力来使其他框架更加依赖于依赖项注入,这很有用,因为这样做时它们经常使用最佳实践(JMS,ORM,OXM,MVC等)。

参考文献


1
我从别人那里学到的东西(而不是我自己使用的)是,PicoContainer的重量比Guice轻。另外,尽管查看了PicoContainer文档,但它似乎也更易于使用。它将在构造函数本身中搜索依赖项,而您无需指定要使用的构造函数。它只使用一个匹配的。
Kissaki 2010年

2
是的,我本人现在很喜欢PicoContainer。这只是一个“保持简单”而又可行的解决方案,我不禁将Spring视为肿和过时的。Guice也很好(并且有很好的支持者,带有Google),但是我相信 Pico的功能也比较灵活,而且会变老。很高兴看到讨厌的xml配置的不错替代品!
Manius 2010年

参照上面对Pico的“未广泛使用”的描述,确实它不如其他Pico受欢迎,但是考虑到它比其他解决方案更小/更简单,因此您不太可能遇到异常问题。如果您这样做,将有一个不错的响应非常迅速的邮件列表。而且Pico是非侵入性的(除非您决定使用批注,这是一个选择),您不需要像Guice这样的批注,这意味着减少注入代码的工作。(是的,我有偏见,但是Pico就是这么酷),但是Guice当然是一个很好的DI工具(比Spring IMO更好)。
Manius 2010年

1
我在许多非常大(且使用率很高)的项目中使用了pico(每个容器中定义了数百个组件类型),并使用了其所有各种功能,并且对此感到不满意。
jhouse 2011年

2
我只是使用Guice / Spring / PicoContainer进行了简单的性能测试-Guice和PicoContainer相当相似。在某些情况下,Guice快一些。在所有情况下春天都非常缓慢。
约书亚·戴维斯

25

jamie.mccrindle给出的答案实际上是很好的,但是当很明显有更好的选择(包括Pico和Guice)可用时,为什么让Spring是默认选择却让我感到困惑。IMO Spring的受欢迎程度已经达到顶峰,现在它已经摆脱了大肆宣传(以及其他所有希望借助Spring潮流的“我也是” Spring子项目)。

Spring的唯一真正优势是社区规模(坦率地说,由于规模和复杂性,这是必需的),但是Pico和Guice 不需要庞大的社区,因为它们的解决方案更干净,更有条理且更优雅。Pico似乎比Guice灵活(您可以在Pico中使用注释,也可以不使用注释-这非常有效)。 (编辑:是要说它非常灵活,而不是说它也不是很有效。)

Pico的体积小且没有依赖关系,这是一次重大胜利,不容小.。您现在需要下载几兆才能使用Spring?这是一个巨大的jar文件的杂乱无章,并带有所有的依赖关系。凭直觉思考,这样一种有效的“小型”解决方案应该比Spring这样的扩展和性能更好。Spring的膨胀真的会使其规模更好吗?这是古怪的世界吗?在证明(并说明)之前,我不会假设Spring具有“更大的可扩展性”。

有时创建一些好东西(Pico / Guice),然后使您的HANDS保持关闭,而不是通过无休止的新版本添加膨胀和厨房水槽功能,确实可以解决问题……


1
小心地说为什么 Pico和Guice优于Spring?
托尔比约恩Ravn的安德森

4
我以为我做过-基本上,他们也做DI,它们更简单/更小/更干净,并且没有或只有很少的依赖项。这并不是说,春节永远是有道理的(我敢肯定有这样的情况),我想说的是,简单的是是否达到您的要求更好。对于大量项目,您只需要小的支持库。
Manius

12

注意:这更多的是评论/回应而不是答案

PicoContainer很棒。如果他们只是修复他们的网站,我会切​​换回去。现在真的很混乱:

我现在正在使用Guice 2.x,尽管它更大,并且功能更少。查找文档非常容易,并且用户组非常活跃。但是,如果Guice 3的方向有任何迹象,那么Guice似乎开始膨胀,就像Spring早年回归一样。

更新:我向Pico Container员工发布了评论,他们对网站进行了一些改进。现在好多了!


但是codehaus网站仍然冻结,没有任何举动的信息。我以为Pico已经死了;)
弗拉迪斯拉夫·拉斯特鲁斯尼

1
如果网站不是最新的代码,则可能表明该项目已降至临界数量以下。
托尔比约恩Ravn的安德森

@ThorbjørnRavnAndersen是的。不幸的是,我认为Pico已被Guice和CDI取代。
约书亚·戴维斯

5
截至2013年3月8日,picocontainer.org网站似乎已被域名抢注者占用。picocontainer.com现在似乎是规范的网站。
dOxxx

2

这是一个老问题,但是今天您可以在Android App项目中考虑使用Dagger(https://github.com/square/dagger)。Dagger在编译时进行代码生成。这样您可以缩短启动时间,并减少执行时间上的内存使用量。


我喜欢Dagger,但似乎在公共仓库中还没有针对非Android项目的Gradle插件(例如,针对“常规” Java项目的Gradle插件)。如果公共存储库中有插件,我会考虑将其用于Java项目。
约书亚·戴维斯

2

如果您追求简约的DI容器,可以查看Feather。仅具有Vanilla JSR-330 DI功能,但在占用空间(16K,无依赖项)和性能方面都相当不错。适用于android。


嘿,羽毛真棒!我用它来实现一个DI插件ActFramework。我做了一些更新,例如在需要时自动调用injectFields以及对注入侦听器的支持,如果您希望我发送回拉请求,请告诉我
Gelin Luo

@green我看到你已经搬到了Genie。您能否分享一下使用Feather的经验?
BeerBear

1
@beerBear Feather非常轻巧,在大多数DI用例中都非常易于使用。但是,由于我正在研究全栈MVC框架,因此我需要一个实现完整JSR330规范的解决方案。这就是为什么我搬到Genie
Gelin Luo

@green感谢您发表的解释,以使您更好地理解。
啤酒熊

0

尽管我喜欢PicoContainer的原因在于它的简单性和缺乏依赖性。我建议改用CDI,因为它是Java EE标准的一部分,因此您没有供应商锁定。

在侵入性方面,主要问题是需要一个容器并使用相对空的META-INF / beans.xml文件(需要表明jar正在使用CDI)和使用注释(尽管它们是标准的) )

我用于自己的项目的轻型CDI容器是Apache Open Web Beans。尽管花了一段时间才弄清楚如何创建一个像这样的简单应用程序(与Pico不同)。

public static void main(final String[] args) {
    final ContainerLifecycle lifecycle = WebBeansContext.currentInstance()
            .getService(ContainerLifecycle.class);
    lifecycle.startApplication(null);

    final BeanManager beanManager = lifecycle.getBeanManager();
    // replace Tester with your start up class
    final Bean<?> bean = beanManager.getBeans(Tester.class).iterator()
            .next();

    final Tester b = (Tester) lifecycle.getBeanManager().getReference(bean,
            Tester.class, beanManager.createCreationalContext(bean));
    b.doInit();
}

2
如果您在库代码中坚持使用JSR-330,则可以将特定于容器的代码保持在最低限度。
托尔比约恩Ravn的安德森

在自动化测试中,您仍然需要特定于容器的代码。尽管这并不意味着您将在实际代码中包含特定于容器的代码(并且除非您计划运行自己的“主”程序,否则您不应该这样做,在我为自己编写的一个应用程序中,我确实做到了。)
Archimedes Trajano
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.