方法注入在Spring中是很少用的,主要應用是, 對象中可能定義了一個受保 護的抽象方法,而容器可能在運行時實現他以返回由容器查詢得到的對象。
方法注入的最好用途之一就是處理單態、無狀態對象需要調用非單態、有狀 態或者非線程安全對象的情況。
以前剛接觸Spring時,如果在單例bean中調用非單例bean,只要把那個非單 例bean 的singleton設置為false就可以了。其實不然,大家想,我們創建了一 個單例對象,在此單例對象中所用到的其它bean也只會創建一次——(大多數情 況是這樣的,當然我們要解決的就是這個問題)。所以說,單純的把非單例bean 的屬性singleton設為false是解決不了的。此時就是方法注入大顯身手的時候了 。
下面的例子是單例調用單例的情況:我們在service層調用DAO層
/**
*@authorzhu國輝
*/
packagecom.zgh.spring.dao;
importjava.util.List;
importorg.springframework.orm.hibernate3.support.HibernateDaoSupport;< BR> /**
*記住一定要引入org.springframework.orm. (hibernate3).support.HibernateDaoSupport
*也就是此類的父類.
*@authorzhu國輝
*
*/
publicclassUserLoginDaoextendsHibernateDaoSupportimplementsIUserLoginD ao{
inti=0;
publicListgetUser(Stringusername,Stringpassword){
System.out.println("i="+(++i));
System.out.println(username+":"+password);
Listusers=getHibernateTemplate().find ("fromUseruwhereusername=?andpassword=?",newObject[] {username,password});
returnusers;
}
}
為了查看效果,我們在DAO中聲明了一個成員變量(變成有狀態bean)
下面是Service層:
/**
*@authorzhu國輝
*/
packagecom.zgh.spring.service;
importjava.util.List;
importcom.zgh.spring.dao.IUserLoginDao;;
publicclassUserLoginServiceimplementsIUserLoginService{
privateIUserLoginDaouserLoginDao;
publicvoidsetUserLoginDao(IUserLoginDaouserLoginDao){
this.userLoginDao=userLoginDao;
}
publicListgetUser(Stringusername,Stringpassword){
returnuserLoginDao.getUser(username,password);
}
}
這是最基本的形式了,單例調用單例,每次程序運行時,DAO裡的i都會+1, Spring的配置文件如下:
<!--====================DAO=======================-- >
<beanid="userLoginDao"class="com.zgh.spring.dao.UserLoginDao"> <propertyname="sessionFactory">
<reflocal="mySessionFactory"/>
</property>
</bean>
<!--====================Service=======================-->
<beanid="userLoginService"class="com.zgh.spring.service.UserLoginSe rvice">
<propertyname="userLoginDao">
<reflocal="userLoginDao"/>
</property>
</bean>
那麼我們簡單的把userLoginDao中添加屬性singleton="false",如下:
<beanid="userLoginDao"class="com.zgh.spring.dao.UserLoginD ao"singleton="false">
<propertyname="sessionFactory">
<reflocal="mySessionFactory"/>
</property>
</bean>
我們再運行,i打印出來的還是每被訪問一次就+1,也就是說只靠 singleton="false"是不行的,下面我們進行正題:
我們選修改一下 Service:
/**
*@authorzhu國輝
*/
packagecom.zgh.spring.service;
importjava.util.List;
importcom.zgh.spring.dao.IUserLoginDao;;
publicabstractclassUserLoginServiceimplementsIUserLoginService{
protectedabstractIUserLoginDaogetUserLoginDao();
publicListgetUser(Stringusername,Stringpassword){
returngetUserLoginDao().getUser(username,password);
}
}
看看我們都做了什麼事:把類聲明成abstract,定義一個抽象方法: getUserLoginDao();在使用IUserLoginDao的地方直接使用getUserLoginDao()方 法。DAO層沒有什麼變化,下面看一下XML配置文件:
<!--====================DAO=======================-- >
<beanid="userLoginDao"class="com.zgh.spring.dao.UserLoginDao"single ton="false">
<propertyname="sessionFactory">
<reflocal="mySessionFactory"/>
</property>
</bean>
<!--====================Service=======================-->
<beanid="userLoginService"class="com.zgh.spring.service.UserLoginSe rvice">
<lookup-methodname="getUserLoginDao"bean="userLoginDao"/>
</bean>
大功告成:運行結果看看,第次i打印的結果都是1,也就是說每次都生成了 新的UserLoginDao實例。在最後的這個XML中,我們先把DAO的屬性singleton設 置為false,然後在Service中用<lookup-method>配置他的依賴,name指 定類中的抽象方法,bean指定要注入的類。如此而以。