自动装配协作者
Spring 容器可以自动装配协作 Bean 之间的关系。您可以通过检查 ApplicationContext
的内容,让 Spring 自动为您的 Bean 解析协作者(其他 Bean)。自动装配具有以下优势
-
自动装配可以显著减少指定属性或构造函数参数的需要。(其他机制,例如本章其他地方讨论的 Bean 模板,在这方面也很有价值。)
-
随着对象的发展,自动装配可以更新配置。例如,如果您需要向类添加依赖项,则可以自动满足该依赖项,而无需修改配置。因此,自动装配在开发过程中特别有用,同时也不会否定在代码库变得更稳定时切换到显式装配的选项。
当使用基于 XML 的配置元数据(请参阅依赖注入)时,您可以使用 <bean/>
元素的 autowire
属性为 Bean 定义指定自动装配模式。自动装配功能有四种模式。您可以为每个 Bean 指定自动装配,从而可以选择要自动装配的 Bean。下表描述了四种自动装配模式
模式 | 说明 |
---|---|
|
(默认)不进行自动装配。Bean 引用必须通过 |
|
按属性名称自动装配。Spring 查找名称与需要自动装配的属性相同的 Bean。例如,如果一个 Bean 定义设置为按名称自动装配,并且它包含一个 |
|
如果容器中恰好存在一个属性类型的 Bean,则允许自动装配该属性。如果存在多个,则会抛出一个致命异常,这表明您可能无法对该 Bean 使用 |
|
类似于 |
使用 byType
或 constructor
自动装配模式,您可以连接数组和类型化集合。在这种情况下,容器中所有与预期类型匹配的自动装配候选者都将被提供以满足依赖关系。如果预期的键类型为 String
,则可以自动装配强类型化的 Map
实例。自动装配的 Map
实例的值包含所有与预期类型匹配的 Bean 实例,而 Map
实例的键包含相应的 Bean 名称。
自动装配的局限性和缺点
当在整个项目中一致地使用自动装配时,它效果最佳。如果通常不使用自动装配,那么仅使用它来连接一两个 Bean 定义可能会让开发人员感到困惑。
考虑自动装配的局限性和缺点
-
property
和constructor-arg
设置中的显式依赖项始终会覆盖自动装配。您无法自动装配简单的属性,例如基本类型、Strings
和Classes
(以及此类简单属性的数组)。此限制是设计使然。 -
自动装配不如显式装配精确。尽管如前面的表格所述,Spring 谨慎避免在可能产生意外结果的歧义情况下进行猜测。Spring 托管的对象之间的关系不再被显式记录。
-
连接信息可能无法提供给可能从 Spring 容器生成文档的工具。
-
容器中的多个 Bean 定义可能与设置方法或要自动装配的构造函数参数指定的类型匹配。对于数组、集合或
Map
实例,这未必是问题。但是,对于期望单个值的依赖项,这种歧义不会被任意解决。如果找不到唯一的 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
属性的显式值 true
或 false
始终优先。对于此类 Bean,模式匹配规则不适用。
这些技术对于您永远不想通过自动装配注入到其他 Bean 中的 Bean 很有用。这并不意味着被排除的 Bean 本身不能使用自动装配进行配置。相反,Bean 本身不是自动装配其他 Bean 的候选对象。
从 6.2 版本开始, 当使用 限定符 时,标记为 相反, |