[置顶] Spring的自动装配
采用构造函数注入,以及setter方法注入都需要写大量的XML配置文件,这时可以采用另一种方式,就是自动装,由Spring来给我们自动装配我们的Bean.
Spring提供了四种自动装配类型
1:ByName 采用这种方式时给属性自动注入值时,会根据Bean里的setXXX中的XXX去搜寻有没有id=XXX的Bean,有的话,将其自动注入,没有的话,就表示setXXX里要装入属性没有装配值。
2:ByType 采用这种方式给属性自动注入值时,会根据Bean里的setXXX中的参数类型来搜寻配置文件中的Bean定义,如果发现了一个,就自动将其注入,否则如果有0个这个属性没有被装配,如果有多个,则会抛出异常。
3:constructor 这种方式的注入与ByType其实没什么区别,无非是将ByType移入到了构造函数中,这种方式下,构造函数是自动注入的,在构造对象时,会自动根据构造函数的参数类型搜寻Bean,如果有一个合适的,则成功,一个没有,则失败,有多个,则会抛出异常。
4:autodetect 自动检测方式,会采用如下流程,先按照constructor方式,再按照ByType方式。
例子源代码如下
例子一个Java工程师从一个网站上买东本
一个普通的JavaBean
interface Engineer{ Object buyApple(); } public class JavaEngineer implements Engineer{ private String name; private Website ws; public JavaEngineer(String name){ this.name=name; } public void setWebsite(Website ws){ this.ws=ws; } @Override public String toString() { // TODO Auto-generated method stub return super.toString(); } public Object buyApple(){ System.out.print("工程师"+name); return ws.buyApple(); } }
这个网站假设是淘宝网:
interface Website{ Object buyApple(); } public class TaobaoWebsite implements Website { public TaobaoWebsite() { } public Object buyApple() { System.out.println("购买了一个苹果"); return new Object(); } }
则采用自动装配的ByName方式,的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- 这个名字要和setXXX中的XXX保持一致,不区分大小写 --> <bean id="website" class="com.pp.TaobaoWebsite"/> <bean id="engineer" class="com.pp.JavaEngineer" autowire="byName"> <constructor-arg value="ppTest"/> <!-- 这里有一个属性采用的是自动byName的方式注入的 --> </bean> </beans>
打印结果如下:
工程师ppTest购买了一个苹果
有了第一个结果后,第二个结果也就很简单了
ByType的测试
修改配置文件如下
<!-- 这个名字 不再需要和setXXX中的XXX保持一致--> <bean id="web" class="com.pp.TaobaoWebsite"/> <bean id="engineer" class="com.pp.JavaEngineer" autowire="byType"> <constructor-arg value="ppTest"/> <!-- 这里有一个属性采用的是自动byName的方式注入的 --> </bean>
其他的地方可以不用修改。
Constructor自动装配,为了测试,给JavaEngineer加入一个构造函数,如下方式
public JavaEngineer(Website ws){ this.ws=ws; this.name="ppTest"; }
再修改配置文件如下
<bean id="web" class="com.pp.TaobaoWebsite"/> <bean id="engineer" class="com.pp.JavaEngineer" autowire="constructor"> <!--<constructor-arg value="ppTest"/>--> <!-- 这里有一个属性采用的是自动byName的方式注入的 --> </bean>
结果是一样的。
自动装配autodetect,通过将autowire设置为autodetect,是指示Spring容器让它先尝试使用constructor自动装配,如果没有找到合适的Bean,就尝试使用ByType自动装配,新版本中好象已经没有这个属性了。