ActionServlet的初始化過程

來源:互聯網
上載者:User

 

一:介紹

在tomcat的啟動過程中,tomcat會讀取/WEB-INF/web.xml檔案中的配置資訊進行一些初始化的工作,而Struts的啟動工作就從這裡開始.
在web.xml檔案中有如下的配置資訊:

<servlet><br /> <servlet-name>action</servlet-name><br /> <servlet-class>org.apache.struts.action.ActionServlet</servlet-class><br /> <init-param><br /> <param-name>config</param-name><br /> <param-value>/WEB-INF/struts-config.xml</param-value><br /> </init-param><br /> <init-param><br /> <param-name>debug</param-name><br /> <param-value>3</param-value><br /> </init-param><br /> <init-param><br /> <param-name>detail</param-name><br /> <param-value>3</param-value><br /> </init-param><br /> <load-on-startup>0</load-on-startup><br /> </servlet><br /> <servlet-mapping><br /> <servlet-name>action</servlet-name><br /> <url-pattern>*.do</url-pattern><br /> </servlet-mapping>

即表示tomcat啟動的時候會初始化org.apache.struts.action.ActionServlet類.

 

ActionServlet繼承了,javax.servlet.http.HttpServlet.是個Servlet當然也就遵循Servlet的生命週期.</p><p>我們這裡複習一下Servlet的生命週期<br /> 1.Servlet執行個體被建立.<br /> 2. 調用init(ServletConfig config )方法.(在HttpServlet中<br /> 實際上在init(ServletConfig config ) 中調用了init()所以<br /> 我們可以覆蓋 init()方法來進行初例化)<br /> 3.接受客戶請求.調用service方法.(在HttpServelt中,會調用doGet<br /> 和doPost)<br /> 4. 調用destroy()方法.<br /> 5.執行個體被銷毀.

二:
Struts的ActionServlet的初始化

首先看一下init()的源碼:

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

1、initInternal()

     -------Initialize our internal MessageResources bundle

該方法初始化Struts的內部資源檔,該檔案路徑由ActionServlet的internalName欄位指定,預設值是org.apache.struts.action.ActionResources,即Struts的JAR包裡的org/apache/struts.action.ActionResources.properties及其國際化版本檔案。該檔案給出了一些應用運行時,由Struts產生的資訊,包括一些異常報錯資訊,從這裡可以看出,我們完全可以讓Struts自身拋出的異常資訊中文化。

2、initOther()

    -----Initialize other global characteristics of the controller  servlet

2.1 如果web.xml裡ActionServlet的配置中給出了config初始化參數,將該參數的值賦給ActionServlet的config欄位;<br />2.2 如果web.xml裡ActionServlet的配置中給出了convertNull初始化參數,如果該參數值是true、yes、on、y、1中的一個,將ActionServlet的convertNull欄位設為true;<br />2.3 如果ActionServlet的convertNull欄位值為true,則覆蓋Apache Commons BeanUtils中幾個基礎資料型別 (Elementary Data Type)封裝類的轉換器的預設實現,使當轉換資料類型失敗時,返回null,預設的實現是拋出異常。

3、initServlet()

     -----Initialize the servlet mapping under which our controller servlet is  being accessed

這個方法挖開後行數不算少,但其主要作用總結就一句話:將web.xml裡ActionServlet配置中的url-pattern的值賦給ActionServlet類的servletMapping欄位。實現方式是用Apache Commons Digester解析web.xml,用Digester內建的CallMethodRule和CallParamRule使web.xml被解析時,自動調用ActionServlet類的addServletMapping(String servletName, String urlPattern)方法。

關於digester類解析xml檔案請參考:

                         http://blog.csdn.net/wl_ldy/archive/2010/10/07/5925710.aspx



4、initChain()

Parse the configuration documents specified by the<br />chainConfig init-param to configure the default {@link<br />org.apache.commons.chain.Catalog} that is registered in the {@link CatalogFactory} instance for this application

5、getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this)

   將ActionServlet執行個體以Globals.ACTION_SERVLET_KEY為key存在ServletContext對象中

6、initModuleConfigFactory()

    如果web.xml裡ActionServlet配置中給出了
configFactory初始化參數,將其值指定的類做為Struts的ModuleConfigFactory,該值應該是一個完全限定類
名,Struts預設ModuleConfigFactory的實現是
org.apache.struts.config.impl.DefaultModuleConfigFactory。

7、// Initialize modules as needed<br /> ModuleConfig moduleConfig = initModuleConfig("", config);<br /> initModuleMessageResources(moduleConfig);<br /> initModulePlugIns(moduleConfig);<br /> initModuleFormBeans(moduleConfig);<br /> initModuleForwards(moduleConfig);<br /> initModuleExceptionConfigs(moduleConfig);<br /> initModuleActions(moduleConfig);<br /> moduleConfig.freeze();<br /> Enumeration names = getServletConfig().getInitParameterNames();<br /> while (names.hasMoreElements()) {<br /> String name = (String) names.nextElement();<br /> if (!name.startsWith(configPrefix)) {<br /> continue;<br /> }<br /> String prefix = name.substring(configPrefixLength);<br /> moduleConfig =<br /> initModuleConfig(prefix,<br /> getServletConfig().getInitParameter(name));<br /> initModuleMessageResources(moduleConfig);<br /> initModulePlugIns(moduleConfig);<br /> initModuleFormBeans(moduleConfig);<br /> initModuleForwards(moduleConfig);<br /> initModuleExceptionConfigs(moduleConfig);<br /> initModuleActions(moduleConfig);<br /> moduleConfig.freeze();<br /> }<br />把這段代碼放到一起說,是因為它們做的是同一件事,只是操作的對象不同。<br />從代碼上很容易看出,while迴圈外和內的代碼做的是同一件事,簡單說就是將web.xml裡給出的Struts設定檔初始化為ModuleConfig對象,將Struts設定檔裡給出的 MessageResource、DataSource、PlugIn也都初始化為對象,然後將這些對象都放到ServletContext裡。<br />不同的是,while迴圈外操作的是web.xml裡 ActionServlet配置中config初始化參數指定的Struts設定檔;while迴圈內操作的是web.xml裡 ActionServlet配置中以"config/"開頭的初始化參數指定的Struts設定檔。<br />while迴圈外的代碼執行完後,會產生一個預設的沒有首碼的 ModuleConfig對象放到ServletContext裡;while迴圈內的代碼執行完後,會產生N個有首碼的ModuleConfig對象放到ServletContext裡,N等於web.xml裡ActionServlet配置中以"config/"開頭的初始化參數的個數,它們的首碼是"config/"後的字串。這個首碼體現在訪問應用的URL中,用來區分各模組,方便團隊開發
 

8、this.initModulePrefixes(this.getServletContext());

  
將上面while迴圈內產生的所有首碼產生一個String數組,放到ServletContext裡。

9、this.destroyConfigDigester();

    將ActionServlet類的configDigester欄位重設為null。


Come from:http://gemini.javaeye.com/category/8491?show_full=true 

 

 

 



聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.