Struts的Acion中如何取得Spring管理的bean
2013-02-28 14:25
281 查看
package com.maywide.sett.commons.web.struts;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.actions.DispatchAction;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.xxx.data.admin.domain.logic.SysAdminFacade;
import com.xxx.sett.commons.LoginInfo;
import com.xxx.sett.commons.constant.ForwardType;
import com.xxx.sett.commons.constant.MessageKey;
import com.xxx.sett.commons.constant.ReqAttributeType;
import com.xxx.sett.commons.utils.EncodeEx;
import com.xxx.sett.commons.utils.StringUtils;
import com.xxx.sett.domain.logic.SettBusiFacade;
import com.xxx.sett.domain.logic.SettBusiconfFacade;
/**
*
*
* <p>Looks up the Spring WebApplicationContext via the ServletContext
* and obtains the PetStoreFacade implementation from it, making it
* available to subclasses via a protected getter method.
*
* <p>As alternative to such a base class, consider using Spring's
* ActionSupport class for Struts, which pre-implements
* WebApplicationContext lookup in a generic fashion.
*
* @author Juergen Hoeller
* @since 30.11.2003
* @see #getPetStore
* @see org.springframework.web.context.support.WebApplicationContextUtils#getRequiredWebApplicationContext
* @see org.springframework.web.struts.ActionSupport
*/
public abstract class BaseAction extends DispatchAction {
private static Logger logger = Logger.getLogger(BaseAction.class);
private SettBusiFacade settBusiFacade;
private SettBusiconfFacade settBusiconfFacade;
private SysAdminFacade sysAdminFacade;
public SysAdminFacade getSysAdminFacade() {
return sysAdminFacade;
}
public SettBusiconfFacade getSettBusiconfFacade() {
return settBusiconfFacade;
}
public void setServlet(ActionServlet actionServlet) {
super.setServlet(actionServlet);
if (actionServlet != null) {
ServletContext servletContext = actionServlet.getServletContext();
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
this.settBusiFacade = (SettBusiFacade) wac.getBean("settBusiFacade");
this.settBusiconfFacade=(SettBusiconfFacade)wac.getBean("settBusiconfFacade");
this.sysAdminFacade=(SysAdminFacade) wac.getBean("sysAdminFacade");
}
}
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
String isCscomm = request.getParameter("CSCOMM");
if (isCscomm != null && isCscomm.equalsIgnoreCase("true")) {
EncodeEx.change(form);
}
String ajaxkind = request.getParameter("ajaxkind");
if (ajaxkind != null && ajaxkind.equalsIgnoreCase("wfajax")) {
EncodeEx.wfAjaxchange(form);
}
request.setAttribute(MessageKey.COR_MESSAGE, "");
try {
return super.execute(mapping, form, request, response);
} catch (Exception ex) {
ex.printStackTrace();
log.info(ex.getMessage());
ActionForward forward = mapping.findForward(ForwardType.SUCCESS);
request.setAttribute(MessageKey.COR_MESSAGE, ex.getMessage());
saveError(request, ex);
if (forward != null) {
return forward;
} else {
return mapping.findForward(ForwardType.SUCCESS);
}
}
}
public SettBusiFacade getSettBusiFacade() {
return settBusiFacade;
}
public void saveError(HttpServletRequest request, Exception ex) {
request.setAttribute(MessageKey.ERR_MESSAGE, ex.getMessage());
request.setAttribute(MessageKey.DETAIL, ex.toString());
}
public ActionForward doNew(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
return mapping.findForward(ForwardType.CONTENT);
}
}
问题来了,setServlet这个方法有时什么时候被调用,又是在什么地方被调用的呢?为了搞清楚这个问题,我们有必要剖析一下struts1.3.8的源码,从http://struts.apache.org/download.cgi上可以当下来。
首先要从ActionServlet的init方法看起,需要关注的有这么几行代码:
// Initialize modules as needed
ModuleConfig moduleConfig = initModuleConfig("", config);
initModuleMessageResources(moduleConfig);
initModulePlugIns(moduleConfig);
initModuleFormBeans(moduleConfig);
initModuleForwards(moduleConfig);
initModuleExceptionConfigs(moduleConfig);
initModuleActions(moduleConfig);
ModuleConfig这个类其实就是负责解析装配struts config配置文件的类,在initModuleConfig方法中调用了ModuleConfigFactory这个工厂类来创建一个ModuleConfig实例,继续往下看,根据方法名你也能猜到initModuleActions是用来干吗的,在这个方法中通过调用ModuleConfigImp的findActionConfigs方法加载和初始化Action类的,检查一番,发现除了加载配置文件中的Action类之外似乎额外的动作不多,显然我想要找的东西不在这里。
接下来要看的自然是doGet和doPost方法了,方法内部均是调用另外的一个process方法,在这个方法里,我们看到了如下一段代码:
ModuleConfig config = getModuleConfig(request);
RequestProcessor processor = getProcessorForModule(config);
if (processor == null) {
processor = getRequestProcessor(config);
}
processor.process(request, response);
看来关键就在于RequestProcessor的process方法了,看到
// Create or acquire the Action instance to process this request
Action action = processActionCreate(request, response, mapping);
你应该心中有数,离胜利不远了,果然,在processActionCreate方法里
if (instance.getServlet() == null) {
instance.setServlet(this.servlet);
}
终于找到了!就是在这里将ActionServlet对象塞入了Action中。
其实对于技术框架源码的剖析并不是很难,关键在于把握主线,对于一些旁枝末节可以稍后关注。虽然细节上还有待进一步深入探索,但一开始理清脉络才是最重要的,宏观上没有把握,微观上的行为很可能就是盲目的,其实做任何事都是这样的啊。
2.Struts Action 的setServlet() 方法是自动运行的吗?
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.action.ActionServlet;
import org.apache.struts.actions.DispatchAction;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.xxx.data.admin.domain.logic.SysAdminFacade;
import com.xxx.sett.commons.LoginInfo;
import com.xxx.sett.commons.constant.ForwardType;
import com.xxx.sett.commons.constant.MessageKey;
import com.xxx.sett.commons.constant.ReqAttributeType;
import com.xxx.sett.commons.utils.EncodeEx;
import com.xxx.sett.commons.utils.StringUtils;
import com.xxx.sett.domain.logic.SettBusiFacade;
import com.xxx.sett.domain.logic.SettBusiconfFacade;
/**
*
*
* <p>Looks up the Spring WebApplicationContext via the ServletContext
* and obtains the PetStoreFacade implementation from it, making it
* available to subclasses via a protected getter method.
*
* <p>As alternative to such a base class, consider using Spring's
* ActionSupport class for Struts, which pre-implements
* WebApplicationContext lookup in a generic fashion.
*
* @author Juergen Hoeller
* @since 30.11.2003
* @see #getPetStore
* @see org.springframework.web.context.support.WebApplicationContextUtils#getRequiredWebApplicationContext
* @see org.springframework.web.struts.ActionSupport
*/
public abstract class BaseAction extends DispatchAction {
private static Logger logger = Logger.getLogger(BaseAction.class);
private SettBusiFacade settBusiFacade;
private SettBusiconfFacade settBusiconfFacade;
private SysAdminFacade sysAdminFacade;
public SysAdminFacade getSysAdminFacade() {
return sysAdminFacade;
}
public SettBusiconfFacade getSettBusiconfFacade() {
return settBusiconfFacade;
}
public void setServlet(ActionServlet actionServlet) {
super.setServlet(actionServlet);
if (actionServlet != null) {
ServletContext servletContext = actionServlet.getServletContext();
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext);
this.settBusiFacade = (SettBusiFacade) wac.getBean("settBusiFacade");
this.settBusiconfFacade=(SettBusiconfFacade)wac.getBean("settBusiconfFacade");
this.sysAdminFacade=(SysAdminFacade) wac.getBean("sysAdminFacade");
}
}
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
String isCscomm = request.getParameter("CSCOMM");
if (isCscomm != null && isCscomm.equalsIgnoreCase("true")) {
EncodeEx.change(form);
}
String ajaxkind = request.getParameter("ajaxkind");
if (ajaxkind != null && ajaxkind.equalsIgnoreCase("wfajax")) {
EncodeEx.wfAjaxchange(form);
}
request.setAttribute(MessageKey.COR_MESSAGE, "");
try {
return super.execute(mapping, form, request, response);
} catch (Exception ex) {
ex.printStackTrace();
log.info(ex.getMessage());
ActionForward forward = mapping.findForward(ForwardType.SUCCESS);
request.setAttribute(MessageKey.COR_MESSAGE, ex.getMessage());
saveError(request, ex);
if (forward != null) {
return forward;
} else {
return mapping.findForward(ForwardType.SUCCESS);
}
}
}
public SettBusiFacade getSettBusiFacade() {
return settBusiFacade;
}
public void saveError(HttpServletRequest request, Exception ex) {
request.setAttribute(MessageKey.ERR_MESSAGE, ex.getMessage());
request.setAttribute(MessageKey.DETAIL, ex.toString());
}
public ActionForward doNew(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
return mapping.findForward(ForwardType.CONTENT);
}
}
问题来了,setServlet这个方法有时什么时候被调用,又是在什么地方被调用的呢?为了搞清楚这个问题,我们有必要剖析一下struts1.3.8的源码,从http://struts.apache.org/download.cgi上可以当下来。
首先要从ActionServlet的init方法看起,需要关注的有这么几行代码:
// Initialize modules as needed
ModuleConfig moduleConfig = initModuleConfig("", config);
initModuleMessageResources(moduleConfig);
initModulePlugIns(moduleConfig);
initModuleFormBeans(moduleConfig);
initModuleForwards(moduleConfig);
initModuleExceptionConfigs(moduleConfig);
initModuleActions(moduleConfig);
ModuleConfig这个类其实就是负责解析装配struts config配置文件的类,在initModuleConfig方法中调用了ModuleConfigFactory这个工厂类来创建一个ModuleConfig实例,继续往下看,根据方法名你也能猜到initModuleActions是用来干吗的,在这个方法中通过调用ModuleConfigImp的findActionConfigs方法加载和初始化Action类的,检查一番,发现除了加载配置文件中的Action类之外似乎额外的动作不多,显然我想要找的东西不在这里。
接下来要看的自然是doGet和doPost方法了,方法内部均是调用另外的一个process方法,在这个方法里,我们看到了如下一段代码:
ModuleConfig config = getModuleConfig(request);
RequestProcessor processor = getProcessorForModule(config);
if (processor == null) {
processor = getRequestProcessor(config);
}
processor.process(request, response);
看来关键就在于RequestProcessor的process方法了,看到
// Create or acquire the Action instance to process this request
Action action = processActionCreate(request, response, mapping);
你应该心中有数,离胜利不远了,果然,在processActionCreate方法里
if (instance.getServlet() == null) {
instance.setServlet(this.servlet);
}
终于找到了!就是在这里将ActionServlet对象塞入了Action中。
其实对于技术框架源码的剖析并不是很难,关键在于把握主线,对于一些旁枝末节可以稍后关注。虽然细节上还有待进一步深入探索,但一开始理清脉络才是最重要的,宏观上没有把握,微观上的行为很可能就是盲目的,其实做任何事都是这样的啊。
2.Struts Action 的setServlet() 方法是自动运行的吗?
这个方法会在action初始化的时候调用,这样在action初始化的时候就把spring管理的bean付给了action(作为action的全局变量),但是要注意的是在action中只有无状态的对象才能作为action的全局变量哦. private PetStoreFacade petStore; public void setServlet(ActionServlet actionServlet) { super.setServlet(actionServlet); if (actionServlet != null) { ServletContext servletContext = actionServlet.getServletContext(); WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext); this.petStore = (PetStoreFacade) wac.getBean("petStore"); } System.out.println("俺已经初始化了么?"); } 启动tomcat时候,没有输出该语句. 我进入首页后,点击 Enter the Store,控制台输出了该语句,此时执行的DoNothingAction 其代码如下: 代码 public class DoNothingAction extends BaseAction { /* Public Methods */ public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception { return mapping.findForward("success"); } } 所以看来确实是在Action初始化的时候执行的该方法. 不过每次执行一个BaseAction子类,setServlet()方法就要执行一次.
参考资料:http://www.javaeye.com/topic/40646
http://blog.csdn.net/xiehl/article/details/5514668
相关文章推荐
- 如何取得Spring管理的bean
- 如何取得Spring管理的bean (请用第3种方法)
- 如何取得Spring管理的bean
- 如何取得Spring管理的bean
- 如何取得Spring管理的bean
- SpringContextHolder 静态持有SpringContext的引用(如何取得Spring管理的bean )
- Spring MVC 教程,快速入门,深入分析――如何取得Spring管理的bean
- 如何取得Spring管理的bean (请用第3种方法):
- 如何取得Spring管理的bean
- 如何取得Spring管理的bean
- 如何取得Spring管理的bean
- 如何取得Spring管理的bean
- 如何在线程中获取spring 管理的bean
- 如何在线程中获取spring 管理的bean
- 如何在自定义Listener(监听器)中使用Spring容器管理的bean
- 如何使用Spring来管理Struts中的Action
- Spring如何实现管理Bean的。
- 如何使用Spring来管理Struts中的Action
- 如何在自定义Listener(监听器)中使用Spring容器管理的bean