Spring 自动装配
优点:自动装配能显著减少配置的数量。
Spring自动装配的5种模式:
可以使用bean元素的autowire属性来指定bean的装配模式:no、byName、byType、constructor、autodetect
一、No
在每个bean中都一个autowire=default的默认配置它的含义是:
采用beans跟标签中的default-autowire="属性值"一样的设置。
autowire=”default”相当于beans跟标签中的default-autowire=”no”
配置文件:
<!-- 定义一个 真正实现业务的bean的实例,通过scope属性指明业务实例对象的作用域,
prototype代表每次请求都会创建一个新的实例-->
<bean id="GDI" class="cn.csdn.impl.GoodsImpl" scope="prototype"></bean>
<!--创建bean的实例 -->
<bean id="GAction" class=" cn.csdn.ac.GoodsAction" scope="prototype">
<!-- 通过业务实现类属性 gdi的set方法 ref引用的实例注入到gdi属性中-->
<property name="gdi" ref="GDI"></property>
</bean>
cn.csdn.impl.GoodsImpl代码
package ac;
import cn.csdn.impl.GoodsImpl;
public class GoodsAction {
/**定义一个GoodsImpl的操作对象*/
private GoodsImpl gdi;
/**生成相应的set方法 通过set方法注入的*/
public void setGdi(GoodsImpl gdi){
this.gdi = gdi;
}
}
二、byname
根据属性名自动装配。此选项将检查容器并根据名字查找与属性完全一致的bean,并将其与属性自动装配。
配置文件如下:
<bean id="employee" class="cn.csdn.bean.Employee" scope="prototype">
<property name="name"><value>寇晓林</value> </property>
<property name="sex" value="女"></property>
</bean>
<bean id="boss" class=" cn.csdn.bean.Boss" scope="prototype" autowire="byName" >
<property name="name" value="RedArmy"/>
</bean>
<bean id="houremployee" class=" cn.csdn.bean.HourEmployee" scope="prototype">
<property name="money" value="1000"/>
</bean>
cn.csdn.bean.Boss代码
public class Boss {
/**姓名*/
private String name;
/**正式员工*/
private Employee employee;
/**小时工*/
private HourEmployee houremployee;
/**省略相应set方法*/
}
cn.csdn.bean.HourEmployee代码
package spr.bean;
public class HourEmployee extends Employee {
private double money;
/**省略相应的set方法*/
}
cn.csdn.bean.Employee代码
package spr.bean;
public class Employee {
/**员工姓名*/
public String name;
/**员工性别*/
public String sex;
/**省略相应的set方法*/
}
三、byType
在使用的过程中必须保证bean能够初始化,否则的话会出现bug
如果有默认的无参数的构造器就不需要多余的配置
如果有带有参数的构造器,那在bean的配置中必须配置器初始化的参数 或者在bean中添加无参数的构造器
如果容器中存在一个与指定属性类型相同的bean,那么将与该属性自动装配。如果存在多个该类型的bean
那么将会抛出异常,并指出不能使用byType方式进行自动装配。若没有找到相匹配的bean,则什么事都不
发
生,属性也不会被设置。如果你不希望这样,那么可以通过设置dependency-check="objects"
让
Spring抛出异常。
案例如下:
package cn.csdn.service;
public class AddrServiceImpl {
private String address;
public void setAddress(String address) {
this.address = address;
}
}
package cn.csdn.service;
public class CorAddrServiceImpl {
private AddrServiceImpl addrServiceImpl;
public void setAddrServiceImpl(AddrServiceImpl addrServiceImpl) {
this.addrServiceImpl = addrServiceImpl;
}
}
package cn.csdn.service;
public class HomeAddrServiceImpl extends AddrServiceImpl {
private String tel;
public void setTel(String tel) {
this.tel = tel;
}
}
applicatinContext.xml文件配置
<bean id="addrServiceImpl" class="cn.csdn.service.AddrServiceImpl"
scope="singleton">
<property name="address">
<value>河北保定</value>
</property>
</bean>
<bean id="corAddrServiceImpl" class="cn.csdn.service.CorAddrServiceImpl"
autowire="byType" scope="singleton">
</bean>
配置文件这样写一点错都没有,可是在写上:
<bean id="homeAddrServiceImpl" class="cn.csdn.service.HomeAddrServiceImpl"
scope="singleton">
<property name="tel">
<value>1520008xxxx</value>
</property>
</bean>
会不会有错啊
在Spring2.5.6版本会出现错误原因是HomeAddrServiceImpl继承了AddrServiceImpl,IoC容器会认为addrServiceImpl和 homeAddrServiceImpl是相同类型的bean,所以会报一下错误:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'empServiceImpl' defined in file [D:\Workspaces\MyEclipse 8.6\20110419_01\bin\applicationContext.xml]: Unsatisfied dependency expressed through bean property 'companyAddress': : No unique bean of type [cn.csdn.service.AddressServiceImpl] is defined: expected single matching bean but found 2: [homeAddressServiceImpl, addressServiceImpl]; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [cn.csdn.service.AddressServiceImpl] is defined: expected single matching bean but found 2: [homeAddressServiceImpl, addressServiceImpl]
但是,在Spring3.0版本中却没有任何错误。因此,这是大家需要注意的一点!
四、constructor
与byType的方式类似,不同之处在于它应用于构造器参数。如果在容器中没有找到与构造器参数类型一致
的bean,那么将会抛出异常。
package cn.csdn.service;
public class AddressServiceImpl {
/**住址*/
private String address;
public void setAddress(String address){
this.address=address;
}
}
package cn.csdn.service;
public class EmpServiceImpl {
/**公司地址*/
private AddressServiceImpl companyAddress;
public EmpServiceImpl(AddressServiceImpl companyAddress){
this.companyAddress=companyAddress;
}
public EmpServiceImpl(){
}
public void setCompanyAddress(AddressServiceImpl companyAddress){
this.companyAddress=companyAddress;
}
}
package cn.csdn.service;
public class HomeAddressServiceImpl extends AddressServiceImpl {
private String address;
public void setAddress(String address){
this.address=address;
}
public HomeAddressServiceImpl() {
super();
}
public HomeAddressServiceImpl(String address){
this.address=address;
}
}
applicationContext.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd"
default-autowire="no">