自动装配协作对象

Spring容器可以自动装配协作bean之间的关系。您可以让Spring自动解析您的bean所需的协作对象(其他bean),通过检查ApplicationContext的内容。自动装配具有以下优点:

  • 自动装配可以显著减少指定属性或构造函数参数的需要。(其他机制,如在本章其他地方讨论的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定义对自动装配基础设施(包括注解样式配置,如@Autowired)不可用。

autowire-candidate属性仅设计用于影响基于类型的自动装配。它不会影响按名称的显式引用,即使指定的bean未标记为自动装配候选对象,也会解析。因此,按名称自动装配仍会注入一个bean,如果名称匹配。

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

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