对于最新稳定版本,请使用 Spring Framework 7.0.6spring-doc.cadn.net.cn

自动装配协作者

Spring 容器可以自动装配协作 bean 之间的依赖关系。你可以让 Spring 通过检查 ApplicationContext 的内容,自动为你的 bean 解析其协作者(其他 bean)。自动装配具有以下优势:spring-doc.cadn.net.cn

  • 自动装配可以显著减少指定属性或构造函数参数的需求。(本章其他地方讨论的其他机制,例如 bean 模板在这一点上也很有价值。)spring-doc.cadn.net.cn

  • 自动装配可以在对象演进时更新配置。例如,如果你需要向某个类添加一个依赖项,该依赖项可以自动得到满足,而无需你修改配置。因此,在开发阶段,自动装配尤其有用;同时,当代码库变得更加稳定时,你仍然可以选择切换到显式装配。spring-doc.cadn.net.cn

使用基于 XML 的配置元数据时(参见依赖注入),您可以通过autowire元素的<bean/>属性为 bean 定义指定自动装配模式。自动装配功能共有四种模式。您可以为每个 bean 单独指定自动装配方式,从而选择对哪些 bean 启用自动装配。下表描述了这四种自动装配模式:spring-doc.cadn.net.cn

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

nospring-doc.cadn.net.cn

(默认)不进行自动装配。Bean 的引用必须通过 ref 元素来定义。对于大型部署,不建议更改此默认设置,因为显式指定协作者(collaborators)能够提供更好的控制力和清晰度。在某种程度上,这也起到了记录系统结构的作用。spring-doc.cadn.net.cn

byNamespring-doc.cadn.net.cn

按属性名称进行自动装配。Spring 会查找与需要自动装配的属性同名的 bean。例如,如果一个 bean 定义被设置为按名称自动装配,并且它包含一个 master 属性(即它具有一个 setMaster(..) 方法),Spring 就会查找名为 master 的 bean 定义,并使用该 bean 来设置此属性。spring-doc.cadn.net.cn

byTypespring-doc.cadn.net.cn

如果容器中恰好存在一个与属性类型匹配的 bean,则允许该属性被自动装配。如果存在多个这样的 bean,将抛出一个致命异常,表明您不能对该 bean 使用 byType 自动装配。如果没有匹配的 bean,则不执行任何操作(该属性不会被设置)。spring-doc.cadn.net.cn

constructorspring-doc.cadn.net.cn

类似于 byType,但适用于构造函数参数。如果容器中不存在恰好一个该构造函数参数类型的 bean,则会抛出致命错误。spring-doc.cadn.net.cn

在使用 byTypeconstructor 自动装配模式时,您可以装配数组和类型化的集合。在这种情况下,容器中所有与期望类型匹配的自动装配候选 Bean 都会被提供以满足该依赖。如果期望的键类型为 Map,您还可以自动装配强类型的 String 实例。自动装配的 Map 实例的值包含所有与期望类型匹配的 Bean 实例,而该 Map 实例的键则包含对应的 Bean 名称。spring-doc.cadn.net.cn

自动装配的局限性和缺点

当在整个项目中一致地使用自动装配时,其效果最佳。如果通常不使用自动装配,而仅对一两个 Bean 定义使用它来进行装配,可能会让开发人员感到困惑。spring-doc.cadn.net.cn

考虑自动装配的局限性和缺点:spring-doc.cadn.net.cn

  • propertyconstructor-arg 设置中的显式依赖始终会覆盖自动装配。您无法对简单属性(例如基本类型、StringsClasses,以及这些简单属性的数组)进行自动装配。此限制是刻意设计的。spring-doc.cadn.net.cn

  • 自动装配不如显式装配精确。尽管如前表所述,Spring 在存在可能导致意外结果的歧义时会谨慎避免猜测。您由 Spring 管理的对象之间的关系将不再被显式记录。spring-doc.cadn.net.cn

  • 接线信息可能无法提供给那些从 Spring 容器生成文档的工具。spring-doc.cadn.net.cn

  • 容器中可能存在多个 bean 定义与要自动装配的 setter 方法或构造函数参数所指定的类型相匹配。对于数组、集合或 Map 实例而言,这不一定会造成问题。然而,对于期望单一值的依赖项,这种歧义不会被随意解决。如果没有唯一的 bean 定义可用,则会抛出异常。spring-doc.cadn.net.cn

在后一种情况下,你有几个选项:spring-doc.cadn.net.cn

从自动装配中排除 Bean

您可以基于每个 Bean 的粒度,将特定 Bean 排除在自动装配之外。在 Spring 的 XML 格式中,只需将 <bean/> 元素的 autowire-candidate 属性设置为 false。容器会将该特定的 Bean 定义对自动装配基础设施设为不可用(包括诸如 @Autowired 等基于注解的配置风格)。spring-doc.cadn.net.cn

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

您还可以基于与 Bean 名称的模式匹配来限制自动装配候选者。顶层的 <beans/> 元素在其 default-autowire-candidates 属性中接受一个或多个模式。例如,若要将自动装配候选者的范围限制为名称以 Repository 结尾的任意 Bean,请提供值 *Repository。若要指定多个模式,请以逗号分隔的列表形式定义它们。对于某个 Bean 定义的 true 属性显式设置为 falseautowire-candidate 的情况,该设置始终优先。对于这类 Bean,上述模式匹配规则将不再适用。spring-doc.cadn.net.cn

这些技术适用于那些你永远不希望被自动装配注入到其他 bean 中的 bean。这并不意味着被排除的 bean 本身不能通过自动装配进行配置。而是说,该 bean 本身不会作为自动装配其他 bean 的候选对象。spring-doc.cadn.net.cn