Spring笔记---最小化Spring配置

Spring提供了几种技巧,可以帮助减少XML配置数量:
>.自动装配(autowiring):有助于减少甚至消除配置<property>元素和<constructor-arg>元素,让Spring自动识别如何装配Bean的依赖关系。
>.自动检测(autodiscovery):比自动装配更进一步,让Spring自动识别哪些类需要被配置成Spring Bean,从而减少对<bean>元素的使用。

1.自动装配:应对明确的装配场景
涉及自动装配Bean的依赖关系时,Spring提供了如下4中自动装配策略:
>.byName---把与Bean的属性具有相同名字(或ID)的其他Bean自动装配到Bean的对应属性中。如果没有和属性名字相匹配的Bean,则该属性不装配;

>.byType---把与Bean的属性具有相同类型的其他Bean自动装配到Bean的对应属性中。若没有,则该属性不装配;

>.constructor---把与Bean的构造器入参具有相同类型的其他Bean自动装配到Bean构造器对应的入参中;

>.autodetect---首先尝试使用constructor自动装配。若失败,再尝试使用byType自动装配。

(1).byName
eg.
<bean id="kenny" class="spring.domain.Instrumentalist">
 <property name="song" value="Jingle Bells" />
 <property name="instrument" ref="piano" />
</bean>

这里,我们使用property属性显示配置了Kenny的instrument属性。
但是,如果我们使用<bean>定义Piano时,把Bean的id属性设置为instrument:
<bean id="piano" class="spring.domain.Piano">
在上面的例子中,Piano Bean的id属性与kenny Bean的instrument属性的名字是一样的,Spring可以利用此信息自动装配kenny的instrument属性:
<bean id="kenny" class="spring.domain.Instrumentalist" autowire="byName">
 <property name="song" value="Jingle Bells" />
</bean>

byName自动装配遵循一项约定:为属性自动装配ID与该属性名字相同的Bean。通过设置autowire属性为byName,Spring将特殊对待kenny的所有属性,为这些属性寻找与其名字相同的Spring Bean。


(2).byType自动装配:
类似于byName自动装配,只不过不再匹配属性的名字而是检查属性的类型。当使用byType自动装配时,Spring会寻找与属性类型相匹配的Bean。

存在的问题是:当有多个Bean的类型与匹配的属性类型相同,Spring会抛异常。可以给对应的Bean配primary属性来增加优先级。实际上默认的都是true,还需要将其他的设置为false。在自动装配时,如果希望排除一些Bean,可以设置排除的Bean的autowire-candidate属性为false。

(3).constructor自动装配;

(4).autodetect自动装配:当配置一个Bean的autowire属性为autodetect时,Spring将首先尝试使用constructor自动装配,如果没有发现与构造器匹配的Bean时,Spring将尝试使用byType自动装配。

(5).默认自动装配:在<beans>元素里配置autowire属性,这个配置将对所有bean生效,但是也可以通过配置具体的<bean>元素的autowire属性来覆盖<beans>元素所配置的默认自动装配策略。

另外,还可以混合使用自动装配和显示装配,以解决有些自动装配(byType)可能产生的装配不确定性问题,显示装配将覆盖自动装配。

2.使用注解自动装配:
sprng2.5开始,Spring开始支持注解自动装配。
Spring容器默认禁用注解装配。因此,使用前要在Spring配置中启用它。最简单的启用方式是使用Spring的context命名空间配置中的<context:annotation-config>元素。
Spring支持几种不同的用于自动装配的注解:
>.Spring自带的@Autowired注解;
>.JSR-330的@Inject注解;
>.JSR-250的@Resource注解。

1).autowired自动装配:
如果使用@Autowired让spring自动装配演奏家(Instrumentalist)Bean的instrument属性。则可以通过以下方法标注实现:
>.标注setInstrument()方法
@Autowired
public void setInstrument(Instrument instrument)
{
    this.instrument = instrument;
}
这样,就可移除定义Instrumentalist的instrument属性所对应的<property>元素了。当Spring发现对setInstrument()方法使用了@Autowired注解时,Spring会尝试对该方法执行byType自动装配。
>.标注需要自动装配Bean应用的任意方法:
@Autowired注解不仅能用来标注setter方法,还可以标注需要自动装配Bean应用的任意方法,
@Autowired
public void anyMethod(Instrument instrument)
{
    this.instrument = instrument;
}
甚至是构造器:
@Autowired
public Instrumentalist(Instrument instrument)
{
    this.instrument = instrument;
}
当对构造器进行标注时,@Autowired注解表示当创建Bean时,即使在Spring的XML配置文件中没有使用<constructor-arg>元素配置Bean,该构造器也需要自动装配。
>.直接标注属性,包括private属性,并删除setter方法:
@Autowired
private Instrument instrument;

@Autowired注解的限制:应用中只能有一个Bean适合装配到@Autowired注解所标注的属性或参数中。如果没有匹配的Bean,或者存在多个匹配的Bean,@Autowired注解就会遇到一些麻烦。
默认情况下,@Autowired具有强契约特征,其所标注的属性或参数必须是可装配的。如果没有Bean可以装配到@Autowired所标注的属性或参数中,自动装配就会失败,抛出NoSuchBeanDefinitionException异常。
对于上面的两个限制:
第一个,没有匹配的,通过设置@Autowired的required属性为false来配置自动装配是可选的
@Autowired(required=false)
private Instrument instrument;
这里,Spring将尝试匹配instrument属性,但是如果没有找到与之匹配类型的Instrument的Bean,应用不会发生任何问题,而instrument属性的值会设置为null。
required属性可以用于@Autowired注解使用的任何地方。但当使用构造器装配时,只有一个构造器可以将@Autowired的required属性设置为true。其他构造只能将required属性设置为false。另外,当使用@Autowired标注多个构造器时,Spring会从满足装配条件的构造器中选择入参最多的那个构造器。
第二个,有多个Bean满足装配条件,并且都可以被装配到属性或参数中,这是为了避免歧义,可以配合使用Spring的@Qualifier注解:
@Autowired
@Qualifier("guitar")
private Instrument instrument;
如上所示,@Qualifier注解将尝试注入ID的guitar的Bean。除了使用Bean的ID来缩小选择范围,还可以通过在Bean上直接使用qualifier来缩小范围。
<bean class="...spring.domain.Guitar">
 <qualifier value="stringed">
</bean>
还可以使用@Qualifier注解来直接标注Guitar类。
除此之外,我们可以创建自定义限定器(Qualifier)。
Spring的@Autowired注解时减少Spring XML配置的一种方法,但使用它的类会引入对Spring的特定依赖。

2).借助@Inject实现基于标准的自动装配
为了统一各种依赖注入框架的编程模型,JCP发布了Java依赖注入规范JSR-330,即@Inject。
和@Autowired一样,@Autowired可以自动装配属性、方法和构造器,但是@Inject没有required属性,所以@Inject注解所标注的依赖关系必须存在,否则抛异常。
除了@Inject注解,JSR-330还提供了一种技巧。与其直接注入一个引用,可以要求@Inject注入一个Provider。Provider接口可以实现Bean引用的延迟注入以及注入Bean的多个实例等功能。
相对于@Autowired的使用@Qualifier,@Inject使用@Named注解来限定歧义的Bean定义。@Named使用方法和@Qualifier类似。另外,JSR-330也包含@Qualifier注解,但是不建议使用,而是鼓励使用该注解来创建自定义的限定器注解,和@Qualifier创建自定义注解一样。
在注解中还可以使用表达式:
@Value("...")
private Stirng song;
自动装配是一种强大的技术,让Spring自动识别出如何将Bean装配在一起,从而帮助我们减少应用中的XML配置。

3.自动检测Bean
为了配置Spring自动检测,需使用<context:component-scan>代替<context:annotation-config>元素。<context:component-scan>除了完成与<context:annotation-config>一样的工作,还允许Spring自动检测Bean和定义Bean。
<context:component-scan base-package="com.spring.domain">
</context:component-scan>
通过上面的配置,<context:component-scan>元素会扫描指定的包及其所有子包,并查找出能自动注册为Spring Bean的类。base-package属性标识了<context:component-scan>元素所扫描的包。
默认情况下,<context:component-scan>查找使用构造型(stereotype)注解所标注的类,这些注解包括:
>.@Component---通用的构造型注解,标识该类为Spring组件;
>.@Controller---标识将该类定义为Spring MVC controller;
>.@Repository---标识将该类定义为数据仓库;
>.@Service---标识将该类定义为服务;
>.使用@Component标注的任意自定义注解。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值