Bean 的5中装配模式
Spring能自动装配bean与bean之间的依赖关系,即无须使用ref 显示指定依赖bean,由BeanFactory检查 XML 配置文件内容,根据某种规则,为bean注入依赖关系,自动装配可作为某个bean的属性,因此可以指定单独bean ,使某些bean使用自动装配。自动装配可以减少配置文件的工作量,但降低来了依赖关系的透明性和清晰性。
使用bean元素的 autowire属性来配置自动装配,其 autowire属性可以接受如下值;
属性 | 介绍 |
---|---|
no | 不使用自动装配。bean依赖必须通过ref元素定义。(在比较大的部署环境中不建议配置) |
byName | 根据属性名自动装配。BeanFactory查找容器中全部的bean,并且找出其中id 属性与属性同名的bean。 |
byType | 根据属性类型自动装配。BeanFactory查找容器全部bean,如果恰好 有一个依赖属性类型相同的bean,就自动装配这个属性;如果有多个这样的bean,就会抛出一个致命异常;如果没有匹配的bean,则什么都不会发生,因而属性不会被设置; |
constructor | 同byType类似,区别是用于构造注的参数,如果在BeanFactory 中,恰好有一个bean与构造器参数类型相同,则会产生一个致命的错误。 |
default | 默认配置 |
1、byName规则
byName规则。指通过名字注入依赖关系。
假如 A 的实现类包含 setB(B b)方法,而Spring 的配置文件包含id 为 b 的bean,那么Spring 会将b对象注入到A的实例中。当Spring 容器为A注入B的实例b时,如果容器中没有与名字匹配的bean时,则抛出异常。
So…看代码:
首先来两个实现类
public class ColorType {
private String color;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public void showColor(){
System.out.println("这里要展示的颜色是:"+color);
}
}
public class Cat {
//这里定义一个 ColorType 类的参数
private ColorType colorType;
/*
这里说明哈:
这里必须要有setter方法
因为需要通过名字自动转配,因此setter方法名必须是: set+bean名。但这里在写bean明的时候首字母要大写;
*/
public void setColorType(ColorType colorType) {
this.colorType = colorType;
}
//调用ColorType 类中的方法
public void catColor(){
colorType.showColor();
}
}
这里 applicationContext.xml 配置文件里面这写的:
<bean id="cat" class="com.ym.test.Cat" autowire="byName"/>
<!--
说明哈:因为是通过 autowire="byName" 属性来自动装配,所以id 命名的时候首字母小写
-->
<bean id="colorType" class="com.ym.test.ColorType">
<property name="color">
<value>黄色</value>
</property>
</bean>
最后测试
@Test
public void aaTest01(){
//通过配置文件获得Spring容Q
ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml");
//获得对象
Cat cat=(Cat)ac.getBean("cat");
cat.catColor();
}
结果
这里要展示的颜色是:黄色
2、byType规则
byType规则,指根据类型匹配来注入依赖关系。
假如A 实例有 setB(B b)方法,而Spring 配置文件中恰有一个类型B 的bean实例,当容器为A注入类型匹配的bean实例时,如果容器中没有一个类型B的实例,或有多于一个的B的实例时,都将抛出异常。
So…看代码:
(a)、这里了只需要改一哈 applicationContext.xml 配置文件里面的autowire 属性参数 :
<bean id="cat" class="com.ym.test.Cat" autowire="byType"/>
<bean id="colorType" class="com.ym.test.ColorType">
<property name="color">
<value>黄色</value>
</property>
</bean>
这里说明哈
在Cat 类中注意到:setter 方法中的参数类型要与容器中bean的类型一致
即:
/*
这里 setColorType(ColorType colorType)中的参数与容器中的bean类型一致
*/
public void setColorType(ColorType colorType) {
this.colorType = colorType;
}
(b)、这里了如果发生下面的情况则报错:
定义一个接口
/*
*接口IType
*/
public interface IType {
void showCty();
void showColor();
}
IType接口的两个实现类
/*
*接口IType 实现类一 ColorType
*/
public class ColorType implements IType {
private String color;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
@Override
public void showColor(){
System.out.println("这里要展示的颜色是:"+color);
}
@Override
public void showCty() {
// TODO Auto-generated method stub
}
}
/*
*接口IType 实现类二 CryType
*/
public class CryType implements IType {
private String cryType;
public String getCryType() {
return cryType;
}
public void setCryType(String cryType) {
this.cryType = cryType;
}
@Override
public void showColor() {
}
@Override
public void showCty() {
// TODO Auto-generated method stub
System.out.println("它的叫声是这样子的:"+cryType);
}
}
来一个Cat 实现类
public class Cat {
private IType itype;
public void setItype(IType itype) {
this.itype = itype;
}
//方法一
public void catColor(){
itype.showColor();
}
//方法二
public void catCry(){
itype.showCty();
}
}
在XML文件配置中如果是这样写的:
<bean id="cat" class="com.ym.test.Cat" autowire="byType" />
<bean id="cryType" class="com.ym.test.CryType">
<property name="cryType">
<value>喵喵...</value>
</property>
</bean>
<bean id="colorType" class="com.ym.test.ColorType">
<property name="color">
<value>黄色</value>
</property>
</bean>
这样就会运行出错;
因为:此时Spring将无法按类型自动装配,因为容器中有两个类型都为 IType 的bean,Spring无法确定为 cat 注入哪个bean。
(c)、当一个bean即使用自动装配依赖,有使用ref显示指定依赖时,则显示指定依赖将覆盖自动装配。
此时XML文件配置中这样写的话不会报错
<bean id="cat" class="com.ym.test.Cat" autowire="byType" >
<!-- 这里显示指定了依赖关系 -->
<property name="itype">
<ref bean="cryType"/>
</property>
</bean>
<bean id="cryType" class="com.ym.test.CryType">
<property name="cryType">
<value>喵喵...</value>
</property>
</bean>
<bean id="colorType" class="com.ym.test.ColorType">
<property name="color">
<value>黄色</value>
</property>
</bean>
结果为:
它的叫声是这样子的:喵喵…
So what I want to say is…
对于大型的应用,这个自动装配最好是莫用。虽然这个自动装配可以减少配置文件的动作量,但是大大降低了依赖关系的清晰性和透明性。由于依赖关系的装配依赖于源文件的属性名,导致bean与bean之间的耦合降低到代码层次,不利于高层次解读