Spring容器可以自动连接协作bean之间的关系。您可以通过检查ApplicationContext的内容,让Spring自动为您的bean装配(其他bean)。自动装配具有以下优点:
- 自动连接可以显著减少指定属性或构造函数参数的需要。(在这方面,本章其他地方讨论的bean模板等其他机制也很有价值。)
- 自动装配可以随着对象的发展而更新配置。例如,如果您需要向类添加依赖项,则无需修改配置即可自动满足该依赖项。因此,在开发过程中,自动装配可能特别有用,而不会在代码库变得更加稳定时否定切换到显式装配的选项。
当使用基于XML的配置元数据时(请参阅依赖项注入),可以使用<bean/>元素的autowire属性为bean定义指定autowire模式。自动布线功能有四种模式。您指定了每个bean的自动布线,因此可以选择要自动布线的bean。下表介绍了四种自动布线模式:
表1。自动装配模式
模式 | 说明 |
---|---|
| (默认设置)无自动装配。Bean引用必须由ref元素定义。对于较大的部署,不建议更改默认设置,因为明确指定协作者可以提供更大的控制和清晰度。在某种程度上,它记录了一个系统的结构。 |
| 按特性名称自动装配。Spring查找与需要自动连接的属性同名的bean。例如,如果一个bean定义按名称设置为autowire,并且它包含一个master属性(也就是说,它有一个setMaster(..)方法),Spring会查找一个名为master的bean定义并使用它来设置属性。 |
| 如果容器中恰好存在一个属性类型的bean,则允许自动连接属性。如果存在多个,则抛出致命异常,这表明您可能不会对该bean使用byType自动布线。如果没有匹配的bean,则不会发生任何事情(未设置属性)。 |
| 类似于byType,但适用于构造函数参数。如果容器中不是恰好有一个构造函数参数类型的bean,则会引发致命错误。 |
使用byType或构造函数自动连接模式,可以连接数组和类型化集合。在这种情况下,提供容器中与预期类型匹配的所有自动连线候选项以满足依赖关系。如果所需的键类型为String,则可以自动连接强类型映射实例。自动连接的Map实例的值由与期望类型匹配的所有bean实例组成,Map实例的键包含相应的bean名称。
自动装配的局限性和缺点
自动装配在整个项目中一致使用时效果最佳。如果通常不使用自动装配,那么使用它只连接一个或两个bean定义可能会让开发人员感到困惑。
考虑自动装配的局限性和缺点:
- 属性和构造函数arg设置中的显式依赖项始终覆盖自动连接。不能自动连接简单属性,如基元、字符串和类(以及此类简单属性的数组)。这种限制是故意造成的。
- 自动装配不如显式装配精确。尽管如前表所示,Spring谨慎地避免猜测,以防出现可能会产生意外结果的歧义。Spring托管对象之间的关系不再被明确地记录。
- 连接信息可能无法用于可能从Spring容器生成文档的工具。
- 容器中的多个bean定义可能与要自动连接的setter方法或构造函数参数指定的类型匹配。对于数组、集合或Map实例,这不一定是个问题。然而,对于期望单个值的依赖项,这种模糊性不会被任意解决。如果没有唯一的bean定义可用,则抛出异常。
在后一种情况下,您有几个选项:
- 放弃自动装配而选择显式装配。
- 如下一节所述,通过将bean定义的autowire候选属性设置为false,避免对其进行自动装配。
- 通过将其<bean/>元素的primary属性设置为true,将单个bean定义指定为主要候选者。
- 使用基于注释的配置实现更细粒度的控制,如基于注释的容器配置中所述。
从自动装配中排除Bean
在每个bean的基础上,您可以将bean从自动装配中排除。在Spring的XML格式中,将<bean/>元素的autowire候选者属性设置为false。容器使特定的bean定义不可用于自动装配(包括注释样式的配置,如@Autowired)。
autowire候选项属性设计为仅影响基于类型的自动连接。它不影响按名称的显式引用,即使指定的bean没有标记为autowire候选者,也会解析这些显式引用。因此,如果名称匹配,则按名称自动装配仍然会注入一个bean。
您还可以根据与bean名称的模式匹配来限制autowire候选者。顶级<beans/>元素在其默认的autowire候选者属性中接受一个或多个模式。例如,要将autowire候选状态限制为名称以Repository结尾的任何bean,请提供值*Repository。要提供多个模式,请在逗号分隔的列表中定义它们。bean定义的autowire候选项属性的显式值true或false始终优先。对于这样的bean,模式匹配规则不适用。
这些技术对于那些永远不想通过自动布线注入到其他bean中的bean非常有用。这并不意味着排除的bean本身不能通过使用自动装配进行配置。相反,bean本身并不是自动连接其他bean的候选者。