自动装配协作者

Spring 容器可以自动装配协作 bean 之间的关联关系。您可以通过检查 ApplicationContext 的内容,让 Spring 自动解析您的 bean 的协作者(其他 bean)。自动装配具有以下优点

  • 自动装配可以显著减少指定属性或构造函数参数的需要。(其他机制,例如本章 其他地方讨论的 bean 模板,在这方面也很有价值。)

  • 自动装配可以随着您的对象演变而更新配置。例如,如果您需要向类添加依赖项,则可以自动满足该依赖项,而无需修改配置。因此,自动装配在开发期间特别有用,不会否定在代码库变得更加稳定时切换到显式装配的选项。

当使用基于 XML 的配置元数据(参见 依赖注入)时,您可以使用 <bean/> 元素的 autowire 属性为 bean 定义指定自动装配模式。自动装配功能有四种模式。您可以为每个 bean 指定自动装配,从而选择哪些 bean 需要自动装配。下表描述了四种自动装配模式。

表 1. 自动装配模式
模式 说明

no

(默认)不自动装配。bean 引用必须通过 ref 元素定义。不建议更改默认设置,尤其是在大型部署中,因为显式指定协作者可以提供更大的控制和清晰度。在某种程度上,它记录了系统结构。

byName

按属性名称自动装配。Spring 会查找与需要自动装配的属性名称相同的 bean。例如,如果一个 bean 定义设置为按名称自动装配,并且它包含一个 master 属性(即,它有一个 setMaster(..) 方法),Spring 会查找一个名为 master 的 bean 定义,并使用它来设置该属性。

byType

如果容器中只存在一个与属性类型完全匹配的 bean,则允许自动装配该属性。如果存在多个匹配的 bean,则会抛出一个致命异常,表明您可能无法对该 bean 使用 byType 自动装配。如果没有匹配的 bean,则不会发生任何事情(该属性不会被设置)。

constructor

类似于 byType,但适用于构造函数参数。如果容器中没有与构造函数参数类型完全匹配的 bean,则会引发致命错误。

使用 byTypeconstructor 自动装配模式,您可以装配数组和类型化集合。在这种情况下,容器中所有与预期类型匹配的自动装配候选者都会被提供来满足依赖关系。如果预期键类型为 String,则可以自动装配强类型 Map 实例。自动装配的 Map 实例的值包含所有与预期类型匹配的 bean 实例,而 Map 实例的键包含相应的 bean 名称。

自动装配的局限性和缺点

当在整个项目中一致地使用自动装配时,效果最佳。如果通常不使用自动装配,那么仅使用它来连接一两个 bean 定义可能会让开发人员感到困惑。

请考虑自动装配的局限性和缺点。

  • propertyconstructor-arg 设置中的显式依赖关系始终会覆盖自动装配。您无法自动装配简单属性,例如基本类型、StringsClasses(以及此类简单属性的数组)。此限制是设计使然。

  • 自动装配不如显式连接精确。尽管如前表所述,Spring 非常小心地避免在可能导致意外结果的歧义情况下进行猜测。您管理的 Spring 对象之间的关系不再被显式记录。

  • 连接信息可能无法提供给可能从 Spring 容器生成文档的工具。

  • 容器中的多个 bean 定义可能与要自动装配的 setter 方法或构造函数参数指定的类型匹配。对于数组、集合或 Map 实例,这并不一定是一个问题。但是,对于期望单个值的依赖关系,这种歧义不会被任意解决。如果没有可用的唯一 bean 定义,则会抛出一个异常。

在后一种情况下,您有几个选择。

  • 放弃自动装配,转而使用显式连接。

  • 可以通过将 bean 定义的 `autowire-candidate` 属性设置为 `false` 来避免自动装配,如 下一节 所述。

  • 通过将 bean 定义的 `<bean/>` 元素的 `primary` 属性设置为 `true` 来指定单个 bean 定义作为主要候选者。

  • 实现基于注解的配置提供的更细粒度的控制,如 基于注解的容器配置 所述。

从自动装配中排除 Bean

在每个 bean 的基础上,可以将 bean 从自动装配中排除。在 Spring 的 XML 格式中,将 `<bean/>` 元素的 `autowire-candidate` 属性设置为 `false`。容器使该特定 bean 定义对自动装配基础设施不可用(包括基于注解的配置,如 @Autowired)。

`autowire-candidate` 属性旨在仅影响基于类型的自动装配。它不影响按名称的显式引用,即使指定的 bean 未标记为自动装配候选者,这些引用也会被解析。因此,如果名称匹配,按名称自动装配仍然会注入 bean。

您还可以根据与 bean 名称的模式匹配来限制自动装配候选者。顶级 `<beans/>` 元素在其 `default-autowire-candidates` 属性中接受一个或多个模式。例如,要将自动装配候选者状态限制为名称以 `Repository` 结尾的任何 bean,请提供 `*Repository` 的值。要提供多个模式,请在逗号分隔的列表中定义它们。bean 定义的 `autowire-candidate` 属性的显式 `true` 或 `false` 值始终优先。对于此类 bean,模式匹配规则不适用。

这些技术适用于您永远不想通过自动装配注入到其他 bean 中的 bean。这并不意味着被排除的 bean 本身不能使用自动装配进行配置。相反,该 bean 本身不是自动装配其他 bean 的候选者。