Spring学习笔记-自动装配

来源:互联网 发布:mac接外置光驱不能读取 编辑:程序博客网 时间:2024/06/05 22:32

问题

当一个Bean需要访问另一个Bean时,就可以显示的指定引用装配它。但是,如果容器能够自动的装配Bean,就可以免去手工配置的麻烦。

解决方案

Spring IOC容器能够帮我们自动装配Bean

模式 描述 no(默认) 不执行自动装配,必须显示的装配依赖 byName 对于每个Bean属性,装配一个同名的Bean byType 对于每个Bean属性,装配类型与之兼容的一个Bean,如果找到超过一个Bean将抛出UnsatisfiedDependencyException异常 Construtor 对于每个构造程序参数,首先寻找与参数兼容的bean,然后选择最多匹配参数的构造程序。对于存在歧义的情况,将抛出UnsatisfiedDependencyException异常 autodetect 如果找到一个没有参数的默认构造程序,依赖将按照类型自动装配。否则,将由构造程序自动装配

用XML自动装配

默认模式是no,但是可以设置根元素default-autowire属性修改。
如下图,将squenceGenerator bean的autowire属性设置为byType并且不设置prefixGenerator属性。然后spring试图尝试类型匹配与PrefixGenerator兼容的Bean。在这个例子中,将自动装配datePrefixGenerator bean
自动装配实例

如果有两个或以上目标类型兼容的Bean 在这中情况下,spring无法确定那个更适合,从而无法自动装配。会抛出如下异常
这里写图片描述

byName

按名称自动装配是另外一种自动装配模式。Spring将试图装配一个类名与该属性名相同的Bean,而不是兼容的类型。因为Bean的name属性在一个容器中是唯一的,按照名称装配不户籍导致歧义。

按照构造程序的自动装配

construtor自动装配模式与byType的工作方式类似,但更复杂一些。对于单个构造程序的Bean,Spring为每个构造参数装配一个兼容的Bean,但对于多构造器的Bean,这个过程更加复杂,spring首先试图为每个构造程序的每个参数找到一个类型兼容的bean,并选择最多匹配参数的构造程序。要非常小心的避免歧义。

自动检测的自动装配

autodetect要求spring在byType和constructor模式中作出决定。如果至少到一个没有参数的默认构造程序,将选择byType,否则constructor模式。

自动装配的依赖检查

如果超过一个候选的自动装配bean,将会抛出UnsatisfiedDependencyException。另一方面,如果byName或byType无法匹配到bean,将可能导致NUllPointerException或者一个值没有初始化,但是如果希望在无法自动装配的时候得到通知,应该讲dependcy-check属性设为objects或者all。objects将通知spring在相同的bean工厂中无法找到协同的bean时发出一个错误,all通知容器在任何作为依赖的简单属性类型(string类型或者原始类型)未被设置时发出一个错误,补充了objects的功能。
这里写图片描述

使用@Autowired和@Resource自动装配Bean

问题

在Bean配置文件中autowire属性进行自动装配一个bean的所有属性,这样的灵活性不足以仅仅装配特定的属性。而且只能通过类型或者名称自动装配。如果这两种策略都不能满足需求,就必须明确的装配Bean。

解决方案

从spring2.5起,自动装配可通过@Autowired和@Resource(在JSR-250:Java平台常见注解中定义)注解一个设值方法、构造程序、字段甚至任意方法自动装配特定的属性。

工作原理

为了使用@Autowired和@Resource进行自动装配,必须在IOC容器中注册一个AutowiredAnnotationBeanProcessor实例

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>

也可以简单的在Bean配置文件中包含<context:annotation-config/>元素,将会自动注册一个AutowiredAnnotationBeanProcessor实例。

@Autowired 可以应用到set方法上
这里写图片描述
在默认情况下,所有带@Autowired 的属性都是必须的,当spring找不到匹配的Bean进行装配的时候,将会抛出一个异常。如果希望这个属性是可选的,将@Autowired 的required属性设置为false。之后如果spring找不到匹配的bean,将不设置该属性。

@Autowired(required=false)

@Autowired 还可以应用到构造函数

public class SquenceGenerator{    @Autowired    public SquenceGenerator(PrefixGenerator prefixGenerator){        this.prefixGenerator = prefixGenerator;    }}

同样可以用在字段上,即使这个字段没有申明为public。这样,你不嫩圣罗合格字段的设值方法或者构造程序声明。Spring将通过反射把匹配的Bean注入这个字段。但是用@Autowired注解非公开的字段将降低代码的可测试性,因为代码将很难进行单元测试(黑盒测试无法使用模拟对象之类的方式操纵这一状态)

@Autowiredprivate PrefixGenerator prefixGeneretor;

还可以应用到一个数组类型的属性上,让Spring自动匹配所有的Bean,如:

@Autowiredprivate PrefixGenerator[] prefixGeneretors;

以及类型安全的集合:

@Autowiredprivate List<PrefixGenerator> prefixGeneretors;

如果Spring注意到@Autowired注解应用到一个关键字为字符串的类型安全java.util.Map,它将在这个Map中添加所有Bean名称与关键字相同的兼容类型Bean。

@Autowiredprivate Map<String,PrefixGenerator> prefixGeneretors;

使用限定符的按类型自动装配

默认情况下,按照类型自动装配在IOC容器中超过一个类型兼容的Bean时无效。但是,Spring允许指定一个候选的Bean,这个Bean的名称在Qualifier注解中提供。

@Autowired@Qualifier("datePrefixGenerator")private PrefixGenerator prefixGeneretor;

完成这项工作,Spring将会试图在IOC容器中查找这个名称的Bean,将其装配到这个属性中去。
这里写图片描述
@Qualifier 注解也可以应用到方法参数中进行自动装配。

public class SquenceGenerator{    @Autowired    public inject(@Qualifier("datePrefixGenerator")PrefixGenerator prefixGenerator){        this.prefixGenerator = prefixGenerator;    }}
按照名称自动装配

如果希望按照名称自动装配Bean属性,可以用到JSR-250@Resource注解,默认情况下Spring将试图找到一个与属性同名的Bean,但要显示的指定name属性

@Resource(name="datePrefixGenerator")private PrefixGenerator prefixGeneretor;
0 0
原创粉丝点击