欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

自动装配和手工装配_我反对自动装配的情况

程序员文章站 2022-05-23 21:47:24
...

自动装配和手工装配

自动装配是一种特殊的装配,其中注入依赖项不是显式的,而是实际上由容器隐式管理的。 本文试图提供一些有关使用自动装配的缺点的相关信息。 尽管以Spring为例,但是相同的推理也可以应用于JavaEE的CDI

自动装配基础

自动装配香料

自动装配具有不同的风格:

  • 按类型自动装配意味着Spring将寻找与setter中使用的类型匹配的可用bean。 例如,对于具有setCar(Car car)方法的bean,Spring将在bean上下文中查找Car类型(或其子类型之一)。
  • 通过名称自动装配意味着Spring搜索策略基于bean名称。 对于前面的示例,Spring将查找一个名为car的bean,而不管其类型如何。 这都需要命名Bean(这里没有匿名Bean),并暗示开发人员负责任何类型的mismatch(如果car Bean是Plane类型)。

自动装配也可以用于构造函数注入。

通过XML配置自动装配

让我们首先消除一些误解:自动装配并不意味着注释。 实际上,自动布线从很早以前就可以通过XML使用,并且可以使用以下语法启用。

<beanautowire="byType"class="some.Clazz"/>

这意味着Spring将尝试使用setter查找合适的类型来填充依赖项。

可选的自动装配参数包括:

  • 按名称:Spring将使用bean名称而不是按类型匹配
  • 构造函数:构造函数注入仅限于按类型
  • 自动检测:使用构造函数注入,但是如果找不到足够的构造函数,则退回到按类型

通过注释配置自动装配

可用的注释如下:

注解 描述 资源

@org.springframework.bean.factory.Autowired

Wires by type

Spring 2.5+

@javax.annotation.Resource

Wires by name

Java EE 5+

@javax.inject.Inject

Wires by type

Java EE 6+

@javax.inject.Qualifier

Narrows type wiring

Java EE 6+

依赖注入就是将您的类彼此分离以使其更具可测试性。 通过注解自动装配将注解的类与注解库紧密耦合。 诚然,对于Spring的@Autowired来说,这比其他应用程序服务器通常提供的其他条件更糟。

到底为什么这么糟糕?

自动装配就是简化依赖注入,尽管乍一看似乎很诱人,但是在现实项目中却无法维护。

显式依赖项注入-猜猜是什么,显式定义单个Bean以匹配所需的依赖项。 更好的是,如果使用Java配置,则在编译时对其进行验证。

相反,自动装配是在Spring上下文中表示对所有可用bean的约束,以便只有一个与所需的依赖项匹配。 实际上,您将接线委托给Spring,让他负责为您找到合适的bean。 这意味着,如果您之前的约束不适用于新的Bean,则通过在上下文中添加Bean会带来提供多个匹配项的风险 项目越大,团队越大(或团队数量甚至更糟),上下文越大,风险越高。

例如,假设您通过一个实现构建了一个真正不错的服务,那么您需要将其注入某个地方。 一段时间后,有人注意到您的服务,但由于某种原因创建了替代实现。 通过在上下文中声明这个新bean以及前者,它将破坏容器的初始化! 更糟糕的是,它可能在应用程序的完全不同的部分中完成,似乎与前者没有任何联系。 至此,好运来分析一下错误的原因。

请注意,按名称自动装配甚至更糟,因为Bean名称即使在不同类型的层次结构中也有可能发生冲突。

在Spring中,自动装配不好,但在CDI中更糟,因为CDI中类路径中的每个类都可以作为注入对象。 顺便说一句,任何阅读这篇文章的CDI专家都将解释为什么自动装配是DI的唯一方法? 那将是真正的启发。

摘要

在这篇文章中,我试图解释什么是自动装配。 可以使用它,但是现在您应该意识到它的缺点。 恕我直言,您只应将其用于原型设计或概念的快速验证,一次使用后可以丢弃的所有内容。 如果确实需要,则首选按类型接线而不是按名称接线,因为至少它的匹配不依赖于字符串。

翻译自: https://blog.frankel.ch/my-case-against-autowiring/

自动装配和手工装配