Java依赖注入:XML或注释

Ily*_*a K 35 java spring dependency-injection guice cdi

注释变得流行.Spring-3支持它们.CDI严重依赖它们(我不能在没有注释的情况下使用CDI,对吧?)

我的问题是为什么

我听到几个问题:

  1. "它有助于摆脱XML".但是xml有什么不好的?依赖性本质上是声明性的,XML对于声明非常有用(对于命令式编程来说非常糟糕).有了很好的IDE(就像想法一样),编辑和验证xml非常容易,不是吗?

  2. "在许多情况下,每个接口只有一个实现".那不是真的!我系统中的几乎所有接口都具有用于测试的模拟实现.

还有其他问题吗?

现在我的XML优势:

  1. 你可以在任何地方注入任何东西(不仅是带有注释的代码)

  2. 如果我有一个接口的多个实现,我该怎么办?使用限定符?但它迫使我的班级知道它需要什么样的注射.它不适合设计.

基于XML的DI使我的代码清晰:每个类都不知道注入,所以我可以配置它并以任何方式对它进行单元测试.

你怎么看?

Col*_*inD 25

我只能用Guice的经验说话,但这是我的看法.缺点是基于注释的配置大大减少了将应用程序连接在一起所需的写入量,并且可以更容易地根据具体内容进行更改...通常甚至不必自己触摸配置文件.它通过使最常见的情况绝对无足轻重而牺牲了使某些相对罕见的情况稍微难以处理.

我认为让课程"不知道注射"太过教条是一个问题.在类的代码中不应该引用注入容器.我绝对同意这一点.但是,我们必须明确一点:注释不是代码.它们本身并没有改变类的行为......你仍然可以创建一个带有注释的类的实例,好像它们根本就不存在一样.所以你可以完全停止使用DI容器并在那里留下注释,这样就不会有任何问题.

当您选择不提供有关类中注入的元数据提示(即注释)时,您将丢弃有关该类所需依赖项的宝贵信息源.您不得不在其他地方重复这些信息(例如XML),或依赖不可靠的魔法,如自动装配,这可能会导致意外问题.

要解决您的一些具体问题:

它有助于摆脱XML

XML配置很多都很糟糕.

  • 这非常冗长.
  • 没有特殊工具,它不是类型安全的.
  • 它要求使用字符串标识符.同样,没有特殊工具支持也不安全.
  • 不利用语言的功能,需要各种丑陋的构造来完成可以通过代码中的简单方法完成的任务.

也就是说,我知道很多人已经使用XML足够长的时间,以至于他们确信它很好,我真的不希望改变他们的想法.

在许多情况下,每个接口只有一个实现

对于应用程序的单个配置(例如,生产),每个接口通常只有一个实现.关键是在启动应用程序时,通常只需要将接口绑定到单个实现.然后它可以用在许多其他组件中.使用XML配置,您必须告诉使用该接口的每个组件使用该接口的特定绑定(如果您愿意,还可以使用"bean").使用基于注释的配置,您只需声明绑定一次,其他所有内容都会自动处理.这非常重要,可以显着减少您必须编写的配置量.这也意味着当您向组件添加新依赖项时,通常不必更改任何有关配置的内容!

你有一些接口的模拟实现是无关紧要的.在单元测试中,您通常只需创建模拟并将其传递给自己...它与配置无关.如果你使用模拟设置一个完整的系统进行集成测试与某些接口......这不会改变任何东西.对于系统的集成测试运行,您仍然只使用1个实现,而您只需配置一次.

XML:你可以随处注入任何东西

您可以在Guice中轻松完成此操作,我想您也可以在CDI中完成此操作.因此,使用基于注释的配置系统绝对不会阻止您这样做.也就是说,我冒昧地说,大多数应用程序中的大多数注入类都是可以添加@Inject到自己的类,如果它还没有.用于注释的轻量级标准Java库(JSR-330)的存在使得更多的库和框架@Inject在将来更容易为组件提供带注释的构造函数.

一个接口的多个实现

限定词就是一个解决方案,在大多数情况下应该没问题.然而,在某些情况下,你想在那里使用在特定的注射类是行不通的参数的预选赛做一些事情......往往是因为你想拥有的多个实例一流的,每个使用不同的接口实现或实例.Guice用一种叫做PrivateModules的东西来解决这个问题.我不知道CDI在这方面提供了什么.但同样,这是一个少数情况下的例子,只要你可以处理它就不值得让你的其余配置受到影响.


Boz*_*zho 10

我有以下原则:配置相关的bean是用XML定义的.其他一切 - 带注释.

为什么?因为您不想在类中更改配置.另一方面,它更容易编写,@Service并且@Inject在您要启用的类中.

这不会以任何方式干扰测试 - 注释只是容器解析的元数据.如果您愿意,可以设置不同的依赖项.

至于CDI - 它有XML配置的扩展,但你是对的,它主要使用注释.这是我不喜欢的东西.


Ait*_*ito 4

正如您所指出的,我喜欢保持代码清晰。XML 在 IOC 原则方面表现得更好,至少对我来说是这样。

配置依赖注入的基本原则是应用程序对象不应该负责查找它们所依赖的资源或协作者。相反,IoC 容器应该配置对象,将应用程序代码中的资源查找外部化到容器中。(不使用 EJB 的 J2EE 开发 - Rod Johnson - 第 131 页)

再说一次,这只是我的观点,没有原教旨主义:)

编辑:一些有用的讨论:

  • 我同意。我并不是说注入违反了 IoC 原则。我试图指出的是,将元数据排除在类之外对我来说更清楚。 (2认同)