Spring学习笔记-自动装配

问题

当一个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注解非公开的字段将降低代码的可测试性,因为代码将很难进行单元测试(黑盒测试无法使用模拟对象之类的方式操纵这一状态)

@Autowired
private PrefixGenerator prefixGeneretor;

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

@Autowired
private PrefixGenerator[] prefixGeneretors;

以及类型安全的集合:

@Autowired
private List<PrefixGenerator> prefixGeneretors;

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

@Autowired
private 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值