特殊情況(ActionForm,Servlet, Filter, Listener)下Spring如何注入對象
學Spring一段時間,理解了一些Spring的注入對象的原理和實例,自己也寫過一些用Spring進行注入對象,特別在SSH整合中這種Spring的注入才體現的淋漓盡致(個人認為),在學習的過程中,難免有些不習慣,原先通過new實例化的對象現在要使用Spring進行bean注入,不過這也應該是Spring的統(tǒng)一管理的細度和好處。(個人理解Spring還不是太深,如果有高人愿意指點一下,非常愿意向您請教)
Spring的注入過程中,有些特殊情況下市不能使用常用的方法進行注入的。最近做個小東西,就發(fā)現了一些特殊情況下不能使用平常我們注入的方法進行注入。
特殊情況一:ActionForm
思考源泉:最近在寫一個程序,要用到Struts1.x中的ActionForm進行一定的驗證,而驗證要使用到數據庫中的數據庫,而我也是和平常一樣使用setXXX來進行注入,但是這個時候就出現了異常,空指針異常。上網搜了很多,雖然沒有具體的,但還是有點思路的。
思路有兩種:
第一種:將你需要注入的參數設置為static的,然后將設值方法setXXX的返回值設置為非void型,比如你的
protected IDaoService daoService;
改為
protected static IDaoService daoService;
設值方法setXXX,為:
public static boolean setDaoService(IDaoService daoService) {
LookuserForm.daoService = daoService;
return true;
}
然后在spring配置文件中設值:
<bean id="BaseBoolean"
class="org.shan.student.form.LookuserForm"
factory-method="setDaoService"
depends-on="daoService">
<constructor-arg ref="daoService"></constructor-arg>
</bean>
這樣就實現了daoService的注射。
我的實例代碼如下:
//下面的是ActionForm里面注入對象的寫法
private static UsersManager um;//靜態(tài),一定
public static boolean setUm(UsersManager um)//非void型的,建議是boolean吧
{
RegisterForm.um = um;
return true;
}
//下面是通過Spring bean的注入,其中id就隨便了,class就是你的ActionForm的類,factory-method就是你的非void型注入對象的方法,depends-on就是你要注入對象使用的bean,constructor-arg ref="XXX"也是一樣了。
<bean id="RegisterForm" class="com.usc.struts.form.RegisterForm" factory-method="setUm" depends-on="UserManager">
<constructor-arg ref="UserManager"></constructor-arg>
</bean>
這樣配置后應該是可以的。我的ActionForm進行用戶驗證的代碼也貼給大家了
/*
* Generated by MyEclipse Struts
* Template path: templates/java/JavaClass.vtl
*/
package com.usc.struts.form;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.ActionErrors;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionMessage;
import org.apache.struts.action.ActionServlet;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.usc.dao.User;
import com.usc.service.UsersManager;
/**
* MyEclipse Struts Creation date: 06-26-2009
*
* XDoclet definition:
*
* @struts.form name="registerForm"
*/
public class RegisterForm extends ActionForm
{
/*
* Generated fields
*/
private static UsersManager um;
public static boolean setUm(UsersManager um)
{
RegisterForm.um = um;
return true;
}
// public UsersManager getUm()
// {
// return um;
// }
// @Override
// public void setServlet(ActionServlet servlet)
// {
// ServletContext context = servlet.getServletContext();
// ApplicationContext ctx = WebApplicationContextUtils
// .getWebApplicationContext(context);
// this.um = ((RegisterForm) ctx.getBean("RegisterForm")).getUm();
// super.setServlet(servlet);
// }
/** password property */
private String password;
/** username property */
private String username;
/** repassword property */
private String repassword;
/*
* Generated Methods
*/
/**
* 注冊驗證 Method validate
*
* @param mapping
* @param request
* @return ActionErrors
*/
public ActionErrors validate(ActionMapping mapping,
HttpServletRequest request)
{
ActionErrors errors = new ActionErrors();
// 用戶名不能為空或者空格組成
if (null == username || "".equals(username.trim())
|| username.trim().length() == 0)
{
errors.add("username", new ActionMessage("username.required"));
// System.out.println("username is required");
} else if (username.trim().length() < 5
|| username.trim().length() > 12)
{
errors.add("username", new ActionMessage("username.error"));
} else if (!um.checkUserName(username))
{
errors.add("username", new ActionMessage("username.error.exist"));
}
// else
// {
// errors.clear();
// }
if (null == password || "".equals(password.trim())
|| password.trim().length() == 0)
{
errors.add("password", new ActionMessage("password.required"));
} else if (!password.trim().equals(repassword))
{
errors.add("repassword", new ActionMessage("repassword.error"));
}
return errors;
}
/**
* Method reset
*
* @param mapping
* @param request
*/
public void reset(ActionMapping mapping, HttpServletRequest request)
{
// TODO Auto-generated method stub
}
/**
* Returns the password.
*
* @return String
*/
public String getPassword()
{
return password;
}
/**
* Set the password.
*
* @param password
* The password to set
*/
public void setPassword(String password)
{
this.password = password;
}
/**
* Returns the username.
*
* @return String
*/
public String getUsername()
{
return username;
}
/**
* Set the username.
*
* @param username
* The username to set
*/
public void setUsername(String username)
{
this.username = username;
}
/**
* Returns the repassword.
*
* @return String
*/
public String getRepassword()
{
return repassword;
}
/**
* Set the repassword.
*
* @param repassword
* The repassword to set
*/
public void setRepassword(String repassword)
{
this.repassword = repassword;
}
}
第二種:重寫ActionForm的public void setServlet(ActionServlet servlet)方法。
public void setServlet(ActionServlet servlet) {
ServletContext context = servlet.getServletContext();
ApplicationContext ctx = WebApplicationContextUtils
.getWebApplicationContext(context);
LookuserFormtemp = (LookuserForm) ctx.getBean("LookuserForm");
this.daoService = temp.getDaoService ();
super.setServlet(servlet);
}
這樣,每次產生一個LookuserForm實例,都會向spring維護的實例請求注入參數。
我的代碼實例如下:
private static UsersManager um;
public static boolean setUm(UsersManager um)
{
RegisterForm.um = um;
return true;
}
<bean id="RegisterForm" class="com.usc.struts.form.RegisterForm" factory-method="setUm" depends-on="UserManager">
<constructor-arg ref="UserManager"></constructor-arg>
</bean>
綜合上面的的注入方法,我個人建議使用第一種,第一種還是和我們以前注入對象的習慣有點類似了。
特殊情況二:服務器啟動以后,(Servlet容器啟動)創(chuàng)建了許多對象,如 servlet, filter, listener,spring等等 那么如何使用這些對象呢
思考源泉:也是在這個程序中用到的,我要使用AJAX技術進行異步驗證,其中有些是要和數據庫進行交互的,網上一般這種情況有兩種驗證思路
思路一:在Javascript中使用JQuery來創(chuàng)建一個XMLHttpRequest對象,再在Action中進行驗證,我使用這個思路做了好久,就是沒有結果,網上也給了很多類似的代碼,但是感覺就沒有一個能夠真正的運行,沒辦法,考慮使用思路二了。
思路二:使用Servlet進行驗證,這種思路很適合AJAX驗證的思路,不過問題出現了,還是空指針異常,Spring注入的對象根本沒有實例化。一開始還以為和Servlet的生命周期有點關系,后來在網上搜了一些東西,還是感覺可以通過Spring進行注入的。
下面介紹在Servlet(或者Filter,或者Listener)中使用spring的IOC容器默認情況下Servlet容器創(chuàng)建spring容器對象,注入到servletContext中,servletContext對象又是注入到session對象中,session對象又是注入到request對象中,request對象又是注入到servlet對象中,(其實不是很標準的注入,是傳參數,或者對屬性直接付值)。層層依賴可以得到spring容器對象。
代碼如下:
ServletContext servletContext = request.getSession().getServletContext();
ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext );
UsersManager um = (UsersManager)ctx.getBean( "UserManager");
這個時候的驗證我在Mozilla Foxfire 和Google Chrome中都通過驗證了,但是在遨游里沒有通過,我不知道是什么原因,望高手指點,謝謝。
上面是我自己寫一個程序中遇到到一些小問題,這應該對理解Spring的依賴注入有很大的好處,通過這個程序,至少讓我們知道了差不多Spring注入對象的一些情況,以后有什么問題了,就非常容易解決。
這里面的代碼都可以給大家了,大家如果需要的話,請下載
(http://usc.googlecode.com/files/UsersManagerWithAJAX.rar),
本博文原word文檔下載地址請移步CSDN
(http://download.csdn.net/source/1540536)
如果有高人指點一下或者相互交流學習的,請聯系QQ:506817493,謝謝。
木子寫于2009年8月2日
博客中的一些下載已經放到了百度云了,請根據需要下載。【點我去百度云下載】
最后弱弱地說一下,如果可以的話,轉載請?zhí)峁┏鎏?
),謝謝。
posted on 2010-01-07 21:11
李順利 閱讀(3233)
評論(2) 編輯 收藏