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