自动装配协作者

Spring容器可以自动装配协作 Bean 之间的关系。你可以让 Spring 通过检查 ApplicationContext 的内容,自动为你的 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 使用 byType 自动装配。如果没有匹配的 Bean,则不执行任何操作(属性未设置)。

constructor

类似于 byType,但适用于构造函数参数。如果容器中不存在且仅存在一个构造函数参数类型的 Bean,则会引发致命错误。

使用 byTypeconstructor 自动装配模式,你可以装配数组和类型化集合。在这种情况下,容器中所有匹配预期类型的自动装配候选都将用于满足依赖。如果预期键类型是 String,则可以自动装配强类型 Map 实例。自动装配的 Map 实例的值由所有匹配预期类型的 Bean 实例组成,而 Map 实例的键包含相应的 Bean 名称。

自动装配的局限性和缺点

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

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

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

  • 自动装配不如显式装配精确。尽管如前面的表格所述,Spring 在可能出现意外结果的歧义情况下会谨慎避免猜测。你的 Spring 管理对象之间的关系不再明确记录。

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

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

在后一种情况下,你有几个选择:

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

  • 通过将其 autowire-candidate 属性设置为 false 来避免对 Bean 定义进行自动装配,如下一节所述。

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

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

从自动装配中排除 Bean

你可以按每个 Bean 的方式,将 Bean 从自动装配中排除。在 Spring 的 XML 格式中,将 <bean/> 元素的 autowire-candidate 属性设置为 false;使用 @Bean 注解时,该属性名为 autowireCandidate。容器使该特定 Bean 定义对自动装配基础设施不可用,包括基于注解的注入点,例如@Autowired

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

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

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

自 6.2 版起,@Bean 方法支持两种自动装配候选标志变体:autowireCandidatedefaultCandidate

使用限定符时,标记为 defaultCandidate=false 的 Bean 仅在存在额外限定符指示的注入点可用。这对于在某些区域应该可注入但不能妨碍其他地方相同类型的 Bean 的受限委托很有用。这样的 Bean 永远不会仅通过纯声明类型注入,而是通过类型加上特定限定符注入。

相比之下,autowireCandidate=false 的行为与上面解释的 autowire-candidate 属性完全相同:这样的 Bean 根本不会通过类型注入。

© . This site is unofficial and not affiliated with VMware.