Spring的注入方式详解

Spring的注入方式详解

2008-04-0114:51:37|分类:Spring|标签:|字号大中小订阅

Spring有三个注入方式,type1,type2,type3

type1接口依赖

type2setter/getter

type3构造方法

type2,type3较用常用

首先来看一下type2

type2 setter/getter(引用注入)

例如,存在一个User类和Home类

user类里一个userName;一个Home对象的属性.

publicclassUser{

privateStringuserName;

privateHomemyHome;

publicHomegetMyHome(){

returnmyHome;

}

publicvoidsetMyHome(HomemyHome){

this.myHome=myHome;

}

publicStringgetUserName(){

returnuserName;

}

publicvoidsetUserName(StringuserName){

this.userName=userName;

}

}

publicclassHome{

privateStringhomeAddr;

publicStringgetHomeAddr(){

returnhomeAddr;

}

publicvoidsetHomeAddr(StringhomeAddr){

this.homeAddr=homeAddr;

}

}

publicclassTestMain{

publicstaticvoidmain(String[]args){

ApplicationContextcontext=newFileSystemXmlApplicationContext("test/lyx/applicationContext.xml");

Useruser1=(User)context.getBean("user");

System.out.println(“姓名为:”+user1.getUserName());

System.out.println(“家庭住址是:”+user1.getMyHome().getHomeAddr());

}

}

将两个bean的注入:(applicationContext.xml配置如下)

<beanid="home"class="test.lyx.Home"abstract="false"

singleton="true"lazy-init="default"autowire="default"

dependency-check="default">

<propertyname="homeAddr">

<value>大连</value>

</property>

</bean>

<beanid="user"class="test.lyx.User"abstract="false"

singleton="true"lazy-init="default"autowire="default"

dependency-check="default">

<propertyname="userName">

<value>liuyuanxi</value>

</property>

<propertyname="myHome">

<refbean="home"/>

</property>

</bean>

这里的userbean,引用了homebean,

运行时会打出 

姓名为:liuyuanxi

家庭住址是:大连

这种方式就是setter/getter方式注入,习惯用JavaBean的人应该很容易理解这种方法,也就是能过<propertyname="userName">来指定属性.<value>liuyuanxi</value>来指定属性所对应的值.多少个属性就有多少个<property>

这里一个人,和家是两个类,也提到了两个bean之间的引用.也就是user bean给名字赋了值,home bean给地址赋了值.如果在userbean中想引入homebean中的地址.就用<ref/>不再用<values>

type3构造方法注入

这里我们在User里加入一个构造器

publicUser(HomemyHome){

this.myHome=myHome;

}

然后 把配置文件改一下:autowire=constructor;

<beanid="home"class="test.lyx.Home"abstract="false"

singleton="true"lazy-init="default"autowire="default"

dependency-check="default">

<propertyname="homeAddr">

<value>大连</value>

</property>

</bean>

<beanid="user"class="test.lyx.User"abstract="false"

singleton="true"lazy-init="default"autowire="constructor"

dependency-check="default">

<propertyname="userName">

<value>liuyuanxi</value>

</property>

<propertyname="myHome">

<refbean="home"/>

</property>

</bean>

运行时会打出 

姓名为:liuyuanxi

家庭住址是:大连

这种方式就是构造器注入

我们再来看看spring的绑定

也就是通过bean属性autowire来设置

1.通过bean属性autowire="byType"的设置可以使用bean在运行时候根据去寻找同类型的已定义属性,如果找不到则处于未绑定状态.(已定义好指在applicationContext.xml中初始化)这里我们把配置文件的 userbean的autowire改成autowire="byType",注意一定要把User的构造器去掉,要不然先找构造器,会出错.这里的homebean是属于,test.lyx.Home类型的,而userbean里有两个属性一个属性已经初始化,而另一个属性Home,就会自动找到.

applicationContext.xml配置如下:

<beanid="home"class="test.lyx.Home"abstract="false"

singleton="true"lazy-init="default"autowire="default"

dependency-check="default">

<propertyname="homeAddr">

<value>大连</value>

</property>

</bean>

<beanid="user"class="test.lyx.User"abstract="false"

singleton="true"lazy-init="default"autowire="byType"

dependency-check="default">

<propertyname="userName">

<value>liuyuanxi</value>

</property>

<propertyname="myHome">

<refbean="home"/>

</property>

</bean>

运行时会打出 

姓名为:liuyuanxi

家庭住址是:大连

这种方式就是构造器注入

但这样的寻找方式有一个弱点,

假如再注入一个Home bean,叫home1,运行时就会找到两个bean,出错.

<beanid="home1"class="test.lyx.Home"abstract="false"

singleton="true"lazy-init="default"autowire="default"

dependency-check="default">

<propertyname="homeAddr">

<value>beijing</value>

</property>

</bean>

如果我们想解决这种问题也很简单,我们可以把autowire改为,autowire="byName"方式来寻找.

但是这里一定要注意:Homebean的id名,一定要和属性名字一样.这里应该改成,id="myHome"

<beanid="home1"class="test.lyx.Home"abstract="false"

singleton="true"lazy-init="default"autowire="default"

dependency-check="default">

<propertyname="homeAddr">

<value>dalian</value>

</property>

</bean>

<beanid="myHome"class="test.lyx.Home"abstract="false"

singleton="true"lazy-init="default"autowire="default"

dependency-check="default">

<propertyname="homeAddr">

<value>北京</value>

</property>

</bean>

这样的话

运行时会打出 

姓名为:liuyuanxi

家庭住址是:北京

而不在是大连了,这种寻找方式就是byName,也就是按属性的名字进行查询.注意:id一定要属性的名字一样.

2.我们来比较一个byname和bytype这两种方式.

byname要比bytype精确些,因为id,是不能重名的.

而且假如存在一这样一种情况,两个userbean,分别为user1,user2,那么user1,user2都可以,打出北京.重用性很好.

到这可能有人会想到.user1,和user2调用的是同一个Home吗.你可以把他们的hashcode();打出来,你会发现地址是一样的,也就是说,是同一个bean.这里是因为singleton="true"的原因,如果你把singleton改成了"false"那就不是一个对象了.

3.如果把autowire=”constructor”也就是构造器注入一定要注意了,他是以byType进行查找,也就是说,Homebean,是不能出现两次,否则就会出错了.

4.如果autowire设置成为autodetect,他会一直找,直到找到一个合适的为止.constructor,bytype,byname的顺序去找.这种方式是不推荐使用的.因为你很难判断出执行的是那个.

相关推荐