程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 層層遞進Struts1(四)之預加載ActionServlet

層層遞進Struts1(四)之預加載ActionServlet

編輯:關於JAVA

Struts的執行相當於分為兩個階段,預加載階段和執行階段,預加載階段是指在Tomcat啟動之時就開始執 行的內容,而此時我們並未真正進入跳轉邏輯,這篇博客我們來分析一下預加載階段。

配置文件

還記得web.xml中關於Struts的Servlet是如何配置的嗎?

  <servlet-

name>action</servlet-name>  
  <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>  
  <init-param>  
    <param-name>config</param-name>  
    <param-value>/WEB-INF/struts-config.xml</param-value>  
  </init-param>  
  <init-param>  
    <param-name>debug</param-name>  
    <param-value>2</param-value>  
  </init-param>  
  <init-param>  
    <param-name>detail</param-name>  
    <param-value>2</param-value>  
  </init-param>  
  <load-on-startup>2</load-on-startup>  
</servlet>  
<!-- Standard Action Servlet Mapping -->
<servlet-mapping>  
  <servlet-name>action</servlet-name>  
  <url-pattern>*.do</url-pattern>  
</servlet-mapping>

其中<load-on-startup>2</load-on-startup>指的就是在 Tomcat啟動之時即執行,實際只要數字大於0,意思就是Tomcat啟動即執行,為了進入調試,我們把這裡改為0 。

<load-on-startup>0</load-on-startup>  

主函數init()

經過調 試發現,當執行完此函數,Struts的預加載階段即結束,所以我們主要來看這個函數即可。

/** 
 * <p>Initialize this servlet.  Most of the processing has been factored into 
 * support methods so that you can override particular functionality at a 
 * fairly granular level.</p> 
 * 
 * @exception ServletException if we cannot configure ourselves correctly 
 */
public void init() throws ServletException {  
      
    // Wraps the entire initialization in a try/catch to better handle  
    // unexpected exceptions and errors to provide better feedback  
    // to the developer  
    try {  
        initInternal();  
        initOther();  
        initServlet();  
      
        getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);  
        initModuleConfigFactory();  
        // Initialize modules as needed  
        ModuleConfig moduleConfig = initModuleConfig("", config);  
        initModuleMessageResources(moduleConfig);  
        initModuleDataSources(moduleConfig);  
        initModulePlugIns(moduleConfig);  
        moduleConfig.freeze();  
      
        Enumeration names = getServletConfig().getInitParameterNames();  
        while (names.hasMoreElements()) {  
            String name = (String) names.nextElement();  
            if (!name.startsWith("config/")) {  
                continue;  
            }  
            String prefix = name.substring(6);  
            moduleConfig = initModuleConfig  
                (prefix, getServletConfig().getInitParameter(name));  
            initModuleMessageResources(moduleConfig);  
            initModuleDataSources(moduleConfig);  
            initModulePlugIns(moduleConfig);  
            moduleConfig.freeze();  
        }  
      
        this.initModulePrefixes(this.getServletContext());  
      
        this.destroyConfigDigester();  
    } catch (UnavailableException ex) {  
        throw ex;  
    } catch (Throwable t) {  
      
        // The follow error message is not retrieved from internal message  
        // resources as they may not have been able to have been   
        // initialized  
        log.error("Unable to initialize Struts ActionServlet due to an "
            + "unexpected exception or error thrown, so marking the "
            + "servlet as unavailable.  Most likely, this is due to an "
            + "incorrect or missing library dependency.", t);  
        throw new UnavailableException(t.getMessage());  
    }      
}

很明顯init函數中執行有其它函數,為了簡明扼要,這些函數的代碼不再完全照搬,碰到重要或是 經典的代碼片段我會放進來。

調用函數

initInternal()

此函數的作用是,初始化內部 文件ActionResources.properties。

initOther()

此函數的作用是:指定struts-config.xml的 路徑,默認為/WEB-INF/struts-config.xml;同時注冊ConvertUtils的數據類型,例如:

ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class);  
ConvertUtils.register(new BigIntegerConverter(null), BigInteger.class);

initServlet()

此函數的作用是:讀取struts在web.xml中的配置信息,例如do/action、url等;獲取web程序部署信 息。

與ModuleConfig相關

getServletContext().setAttribute

(Globals.ACTION_SERVLET_KEY, this);  
            initModuleConfigFactory();  
            // Initialize modules as needed  
            ModuleConfig moduleConfig = initModuleConfig("", config);  
            initModuleMessageResources(moduleConfig);  
            initModuleDataSources(moduleConfig);  
            initModulePlugIns(moduleConfig);  
            moduleConfig.freeze();  
          
            Enumeration names = getServletConfig().getInitParameterNames();  
            while (names.hasMoreElements()) {  
                String name = (String) names.nextElement();  
                if (!name.startsWith("config/")) {  
                    continue;  
                }  
                String prefix = name.substring(6);  
                moduleConfig = initModuleConfig  
                    (prefix, getServletConfig().getInitParameter(name));  
                initModuleMessageResources(moduleConfig);  
                initModuleDataSources(moduleConfig);  
                initModulePlugIns(moduleConfig);  
                moduleConfig.freeze();  
            }

這段代碼的作用是,將web.xml中的Struts配置文件初始化為ModuleConfig對象,將 struts-config中的MessageResource、DataSource、PlugIn也都初始化為對象,保存到ServletContext中。不 同的是,while循環外操作的是web.xml裡 ActionServlet配置中config初始化參數指定的Struts配置文件; while循環內操作的是web.xml裡 ActionServlet配置中以"config/"開頭的初始化參數指定的 Struts配置文件,這樣的區別造成前者會產生沒有前綴的ModuleConfig對象到ServletConfig中,後者會產生 帶前綴的ModuleConfig對象放到ServletContext中,前綴為“config/”後的字符串。

initModulePrefixes(this.getServletContext());

此函數的作用是將循環產生的所有前綴生 成一個String數組,放到ServletContext中。

destroyConfigDigester();

此函數的作用是將 ActionServlet類的configDigester的值改為為null。

執行順序圖

這篇文章主要是分析了在Tomcat啟動時struts的預處理情況,在struts執行邏輯處理時是如 何處理的,請看我的博客《層層遞進Struts1(五)之處理流程》。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved