跳至主要內容

自动装配协作者

会敲代码的程序猿原创SpringSpring Framework大约 5 分钟

自动装配协作者(Autowiring Collaborators)

Spring容器可以自动装配协作Bean之间的关系。 你可以通过检查ApplicationContext的内容,让Spring自动为你的Bean解析协作对象(其他Bean)。

自动装配的优势

  • 减少手动配置:自动装配可以显著减少对手动指定属性或构造方法参数的需求。 其他机制open in new window ,如bean模板,在这方面也是非常有价值的。
  • 动态更新配置:随着项目的发展,对象可能会增加新的依赖。自动装配能够适应这种变化,自动满足新的依赖关系,而无需手动更新配置。 这一点在项目的迭代开发过程中尤为有用。同时,当项目稳定下来后,开发者仍然可以选择切换到显式装配,以获得更精确的控制。

四种自动装配模式

在使用XML配置时, (参阅 依赖注入open in new window), 可以通过<bean/>元素的autowire属性来定义Bean的自动装配模式。 Spring提供了四种自动装配模式,允许你为每个Bean单独指定使用哪种模式。以下是这四种模式的详细描述:

模式描述
no默认模式
不执行自动装配。开发者需要使用ref标签显式声明依赖关系。
byName按名称自动装配
容器会寻找一个属性名称或setter方法名称相匹配的Bean定义将其注入。
例如:Bean的属性名为master(也就是说,它有一个setMaster(..)方法),Spring会寻找名为master的Bean定义来注入。
byType按类型自动装配
容器会寻找与属性类型相匹配的Bean定义将其注入。如果存在多个相同类型的Bean,将抛出异常。
constructor按构造函数参数类型自动装配
容器会寻找与构造函数参数类型相匹配的Bean定义将其注入。如果没有匹配的Bean定义,将抛出异常。这种模式确保了Bean在创建时其必需的依赖就已经被满足。

利用byTypeconstructor自动装配模式,你可以装配数组(array)和泛型集合(collection)。 在这种模式下,Spring容器会自动寻找所有与所需类型相匹配的Bean,并将其注入到定义的数组或集合中,从而满足配置的依赖关系。 此外,当预期的键(key)类型为String时,还可以自动装配一个强类型化的Map实例。 在这个Map中,键(key)将是Bean的名称,而值(value)则是所有匹配期望类型的Bean实例。

这样的自动装配Map实例,为我们提供了一种便捷的方式来管理和访问一组具有相同类型的Bean,特别是当我们需要根据名称快速查找特定的Bean时。

自动装配的局限和缺点

自动装配在项目中保持一致性时效果最佳。如果自动装配没有被普遍采用,而只有少数Bean定义使用它,可能会引起开发人员的困惑。 以下是考虑自动装配时需要注意的限制和缺点:

  1. 显式依赖优先:当存在显式依赖(propertyconstructor-arg)时,自动装配将被忽略
  2. 不适用于基本类型:自动装配不适用于基本类型,如intlongString等,因为它们没有Bean名称
  3. 精确性问题:自动装配不如显式注入精确,因为它依赖于类型匹配,而不是Bean的名称或其他限定符,这可能导致意外的结果
  4. 文档化缺失:自动装配的依赖关系可能不会自动包含在生成的文档中,因此开发者需要额外的文档或注释来解释Bean之间的依赖关系
  5. 多重匹配问题:当存在多个Bean定义与自动装配的属性类型匹配时,Spring将抛出异常
  6. 歧义性:当存在多个Bean定义与自动装配的属性类型匹配时,Spring将无法确定哪个Bean是首选的,就会抛出异常

你有以下几种方法来解决多重匹配问题和歧义性

  • 放弃自动装配,使用显式装配
  • 通过将Bean定义的autowire-candidate属性设置为false来排除Bean
  • 通过将Bean定义的primary属性设置为true来指定首选Bean
  • 实现更细粒度的控制,可以使用基于注解的配置方式, 参阅 基于注解的容器配置open in new window

从自动装配中排除Bean

在每个Bean定义中,你可以设置autowire-candidate属性来控制Bean是否标记为自动装配候选项。

  • 默认情况下,autowire-candidate属性的值为true,表示Bean是自动装配的候选项
  • 属性为false时,Bean将被排除在自动装配之外,这一设置对注解式配置 (如@Autowiredopen in new window)同样有效

注意⚠️autowire-candidate属性仅影响基于类型的自动装配模式。 对于按名称的显示引用,autowire-candidate属性不起作用。 只要名称匹配,它仍然可以被注入。

你还可以根据byName的模式匹配来限制自动装配候选项。 顶层的<beans/>元素接受一个或多个模式,并将其放在 default-autowire-candidates 属性中,以逗号分隔。 例如,要将自动装配候选项限制为任何名称以Repository结尾的Bean,提供值为*Repository

<beans default-autowire-candidates="*Repository">
    <!-- Bean definitions -->
</beans>

Bean定义的autowire-candidate属性显式设置为 true 的值始终具有优先权。 对于这种Bean,不适用于模式匹配规则。

使用这些技术,你可以精确地控制自动装配的行为,避免不期望的依赖注入,确保Bean的自动装配符合你的设计意图。