自动装配协作者
Spring 容器可以自动装配协作 bean 之间的关系。你可以让 Spring 通过检查 ApplicationContext
的内容,为你的 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
设置中的显式依赖项始终会覆盖自动装配。你不能自动装配简单属性,例如基本类型、String
和Class
(以及此类简单属性的数组)。此限制是设计使然。 -
自动装配不如显式装配精确。尽管如前面的表格所示,Spring 会小心避免在可能产生意外结果的歧义情况下进行猜测。你的 Spring 管理对象之间的关系不再显式记录。
-
装配信息可能不适用于可以从 Spring 容器生成文档的工具。
-
容器中的多个 bean 定义可能与 setter 方法或构造函数参数指定的要自动装配的类型匹配。对于数组、集合或
Map
实例,这不一定是问题。但是,对于需要单个值的依赖项,这种歧义不会随意解决。如果没有可用的唯一 bean 定义,则会抛出异常。
在后一种情况下,你有几个选择:
将 Bean 从自动装配中排除
你可以按每个 bean 的方式将 bean 从自动装配中排除。在 Spring 的 XML 格式中,将 <bean/>
元素的 autowire-candidate
属性设置为 false
;对于 @Bean
注解,该属性名为 autowireCandidate
。容器使该特定的 bean 定义不适用于自动装配基础设施,包括基于注解的注入点,例如 @Autowired
。
|
你还可以根据与 bean 名称的模式匹配来限制自动装配候选者。顶级 <beans/>
元素在其 default-autowire-candidates
属性中接受一个或多个模式。例如,要将自动装配候选者状态限制为名称以 Repository
结尾的任何 bean,请提供值 *Repository
。要提供多个模式,请将它们定义为逗号分隔列表。对于 bean 定义的 autowire-candidate
属性的显式值 true
或 false
始终优先。对于此类 bean,模式匹配规则不适用。
这些技术对于你永远不希望通过自动装配注入到其他 bean 中的 bean 很有用。这并不意味着被排除的 bean 本身不能通过使用自动装配进行配置。相反,该 bean 本身不是自动装配其他 bean 的候选者。
从 6.2 版本开始, |