我只能根据 Guice 的经验说话,但这是我的看法。简而言之,基于注释的配置极大地减少了将应用程序连接在一起所需的编写量,并且可以更轻松地更改取决于什么的内容……通常甚至无需接触配置文件本身。它通过使最常见的情况绝对微不足道来做到这一点,但代价是使某些相对罕见的情况稍微更难处理。
我认为对于让课程“不知道注入”过于教条是一个问题。类的代码中不应有对注入容器的引用。我完全同意这一点。但是,我们必须明确一点:注解不是代码。它们本身并没有改变类的行为方式……您仍然可以创建带有注释的类的实例,就好像它们根本不存在一样。因此,您可以完全停止使用 DI 容器并将注释保留在那里,不会有任何问题。
当您选择不在类中提供有关注入的元数据提示(即注释)时,您将丢弃有关该类需要哪些依赖项的宝贵信息来源。您被迫要么在其他地方重复该信息(例如在 XML 中),要么依赖不可靠的魔法,如自动装配,这可能会导致意想不到的问题。
要解决您的一些具体问题:
它有助于摆脱 XML
XML 配置有很多不好的地方。
- 它非常冗长。
- 如果没有特殊工具,它就不是类型安全的。
- 它要求使用字符串标识符。同样,没有特殊工具支持也不安全。
- 没有利用语言的任何特性,需要各种丑陋的结构来完成可以用代码中的简单方法完成的事情。
就是说,我知道很多人使用 XML 的时间已经够长了,以至于他们确信这很好,而且我真的不希望改变他们的想法。
在许多情况下,每个接口只有一个实现
对于应用程序的单个配置(例如生产),每个接口通常只有一个实现。关键是在启动应用程序时,您通常只需要将接口绑定到单个实现。然后可以在许多其他组件中使用它。使用 XML 配置,您必须告诉使用该接口的每个组件使用该接口的这个特定绑定(或“bean”,如果您愿意)。使用基于注解的配置,您只需声明一次绑定其他一切都会自动处理。这非常重要,并且大大减少了您必须编写的配置量。这也意味着当您向组件添加新的依赖项时,您通常根本不需要更改任何配置!
你有一些接口的模拟实现是无关紧要的。在单元测试中,您通常只需创建模拟并将其传递给自己......它与配置无关。如果您设置一个完整的系统来使用某些接口进行集成测试,而不是使用模拟......这不会改变任何事情。对于系统的集成测试运行,您仍然只使用 1 个实现,您只需配置一次。
XML:你可以在任何地方注入任何东西
你可以在 Guice 中轻松地做到这一点,我想你也可以在 CDI 中做到这一点。因此,使用基于注释的配置系统并不会完全阻止您这样做。也就是说,我敢说大多数应用程序中的大多数注入类都是你可以添加@Inject
到自己的类,如果它还没有的话。用于注解的轻量级标准 Java 库 (JSR-330) 的存在使得未来更多的库和框架也更容易为组件提供带@Inject
注解的构造函数。
一个接口的多个实现
限定符是解决此问题的一种方法,在大多数情况下应该没问题。但是,在某些情况下,您确实希望在特定注入类中对参数使用限定符不起作用...通常是因为您希望拥有该类的多个实例,每个实例使用不同的接口实现或实例。PrivateModule
Guice 用一个叫做s 的东西解决了这个问题。我不知道 CDI 在这方面提供了什么。但同样,这种情况是少数,只要你能处理它,就不值得让你的其余配置受到影响。