本文共 3260 字,大约阅读时间需要 10 分钟。
本节书摘来自异步社区《Spring攻略(第2版)》一书中的第1章,第1.11节,作者: 【美】Gary Mak , Josh Long , Daniel Rubio著,更多章节内容可以访问云栖社区“异步社区”公众号查看
1.11.1 问题
当一个Bean需要访问另一个Bean时,你可以显式指定引用装配它。但是,如果你的容器能够自动装配Bean,就可以免去手工配置装配的麻烦。1.11.2 解决方案
Spring IoC容器能够帮助你自动装配Bean。你只要在的autowire属性中指定自动装配模式就可以了。表1-2列出了Spring支持的自动装配模式。尽管自动装配功能非常强大,但代价是降低了Bean配置的可读性。因为自动装配由Spring在运行时执行,你无法从Bean配置文件中得到Bean装配的方式。在实践中,我们建议仅将自动装配应用到组件依赖不复杂的应用程序中。
1.11.3 工作原理
按照类型的自动装配你可以将sequenceGenerator bean的autowire属性设置为byType并且不设置prefixGenerator属性。然后,Spring将试图装配类型与PrefixGenerator兼容的Bean。在这个例子中,将自动装配datePrefixGenerator bean。按照类型的自动装配的主要问题是有时候在IoC类型中具有超过一个与目标类型兼容的Bean。在这种情况下,Spring将无法确定哪个Bean最适合于该属性,从而无法进行自动装配。例如,如果你有另一个以当前年份作为前缀的前缀生成器,按照类型的自动装配将会立即被破坏。
如果找到超过一个可供自动装配的Bean,Spring将会抛出一个UnsatisfiedDependency Exception异常。
Exception in thread "main"org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sequenceGenerator' defined in class path resource [beans.xml]: Unsatisfied dependency expressed through bean property 'prefixGenerator': No unique bean of type [com.apress.springrecipes.sequence.PrefixGenerator] is defined: expected single matching bean but found 2: [datePrefixGenerator, yearPrefixGenerator]
按照名称的自动装配
byName是另一种自动装配模式,有时候它能解决按照类型的自动装配的问题。它的工作方式与byType类似,但是这时候,Spring将试图装配一个类名与该属性名相同的Bean,而不是兼容的类型。因为Bean的name属性在一个容器中是唯一的,按照名称的自动装配不会导致歧义。但是,按照名称的自动装配并不能工作于任何情况。有时候,你不可能使目标Bean的名称与属性相同。在实践中,你往往必须在保持其他依赖自动装配的同时明确地指定歧义的依赖。这意味着你混合了显式装配和自动装配。
按照构造程序的自动装配
constructor自动装配模式与byType的工作方式类似,但是更复杂一些。对于具有单个构造程序的Bean,Spring将试图为每个构造程序参数装配一个具有兼容类型的Bean。但是对于具有多个构造程序的Bean,这一过程就更加复杂。Spring首先试图为每个构造程序的每个参数找到一个类型兼容的Bean。然后,将选择具有最多匹配参数的构造程序。假定SequenceGenerator有一个默认构造程序和一个具有参数PrefixGenerator的构造程序。
package com.apress.springenterpriserecipes.sequence;public class SequenceGenerator { public SequenceGenerator() {} public SequenceGenerator(PrefixGenerator prefixGenerator) { this.prefixGenerator = prefixGenerator; } ...}
在这种情况下,第二个构造程序匹配并且被选中,因为Spring可以找到一个类型与Prefix Generator兼容的Bean。
但是,一个类中的多个构造程序可能造成构造程序参数匹配的歧义。如果你要求Spring确定一个构造程序,情况可能更加复杂。所以,如果你使用这种自动装配模型,就要非常小心地避免歧义。
自动检测的自动装配
自动装配模式autodetect要求Spring在byType和constructor模式中作出决定。如果至少找到一个没有参数的默认构造程序,将选择byType模式,否则,将选择constructor模式。因为SequenceGenerator类定义了默认的构造程序,将选择byType模式。这意味着前缀生成器将通过设值方法注入。自动装配与依赖检查
你已经看到,如果Spring找到超过一个候选的自动装配Bean,将会抛出UnsatisfiedDependency Exception异常。另一方面,如果自动装配模式设置为byName或byType,而Spring无法找到匹配的Bean进行装配,将把该属性保持为未设置状态,这可能导致一个NullPointerException异常或者一个值没有初始化。但是,如果你希望在自动装配无法装配的Bean时得到通知,应该将dependency-check属性设置为objects或者all。在这种情况下,如果自动装配无效将会抛出UnsatisfiedDependencyException异常。objects将通知Spring在相同的Bean工厂中无法找到协同Bean时发出一个错误。all通知容器在任何作为依赖的简单属性类型(String类型或者原始类型)未被设置时发出一个错误,这补充了objects的功能。
转载地址:http://insql.baihongyu.com/