Struts的Acion中如何取得Spring管理的bean

來源:互聯網
上載者:User

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() 方法是自動啟動並執行嗎?

這個方法會在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

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.