Struts配置模組MoudelConfig初始化的實現

來源:互聯網
上載者:User

上回說到Struts的ActionServlet,其中有一步是 initModuleConfig方法,就是用於初始化MoudleConfig執行個體,它是整個org.apache.struts.config包的核心,在Struts應用運行時用來存放整個Struts應用的配置資訊.如果有多個子應用,每個子應用都會有一個ModuleConfig對象.ModuleConfig和Struts設定檔的根項目<struts-config>對應.<struts-config>根項目中包含<form-bean>,<action>和<forward>等一系列子項目,因此MouduleConfig中包含了和每個子項目對應的配置類執行個體.

同時Struts中的MessageResource、PlugIn、資料來源等,都是通過ModuleConfig來實現的,所以在ActionServlet初始化上面的那些模組之前,就先要初始化ModuleConfig,然後由ModuleConfig來負責其初始化。

struts中讀模數塊配置MoudleConfig採用了這樣的Factory 方法
一個介面:ModuleConfig.java
一個抽象類別:ModuleConfigFactory.java
一個ModuleConfig的實作類別:ModuleConfigImpl.java
一個ModuleConfigFactory的子類:DefaultModuleConfigFactory.java

具體介紹
一.initModuleConfigFactory()
在ActionServlet初始化ModuleConfig的時候,先要初始化配置工廠,
代碼 initModuleConfigFactory();  

 

那麼這個工廠到底初始化了什麼。
現看原始碼:
代碼 protected void initModuleConfigFactory(){            String configFactory = getServletConfig().getInitParameter("configFactory");            if (configFactory != null) {                ModuleConfigFactory.setFactoryClass(configFactory);            }    }  
很明顯,現從配置參數取得其配置,如果使用者沒有作配置,那麼就使用預設配置,如果使用者作了配置,那麼就使用使用者的配置。
如果使用者作了配置的話,那麼就執行設定成使用者的工廠。如何設定的呢。
代碼 public static void setFactoryClass(String factoryClass) {        ModuleConfigFactory.factoryClass = factoryClass;        ModuleConfigFactory.clazz = null;    }  
直接給ModuleConfigFactory.factoryClass賦值,因為此變數是一個靜態變數:
代碼 protected static String factoryClass =            "org.apache.struts.config.impl.DefaultModuleConfigFactory";  
由此定義決定了可以使用此賦值方法。正是因為此變數是一個靜態變數,所以在下面的得工廠產生對象的時候就可以建立一個使用者自己的對象。

 

二.initModuleConfig()
之後由配置工廠再執行個體化一個ModuleConfig的對象。
代碼 ModuleConfig moduleConfig = initModuleConfig("", config);  

 

看一下initModuleConfig方法是如何初始化ModuleConfig的,看下面的原始碼:
代碼 protected ModuleConfig initModuleConfig(String prefix, String paths)         throws ServletException {     //這個地方,我們可以看到,此時就由ModuleConfigFactory直接建立了一個工廠對象,而此時我們用的配置就是上面我們初始化後的配置。如果使用者自己做了配置,那麼此時初始化的工廠就是使用者指定後的工廠。如果沒有的話,那麼就初始化的時預設的工廠。    DefaultModuleConfigFactory的一個執行個體            ModuleConfigFactory factoryObject = ModuleConfigFactory.createFactory();         ModuleConfig config = factoryObject.createModuleConfig(prefix);         // Configure the Digester instance we will use         Digester digester = initConfigDigester();            // Process each specified resource path         while (paths.length() > 0) {             digester.push(config);             String path = null;             int comma = paths.indexOf(',');             if (comma >= 0) {                 path = paths.substring(0, comma).trim();                 paths = paths.substring(comma + 1);             } else {                 path = paths.trim();                 paths = "";             }                if (path.length() < 1) {                 break;             }                this.parseModuleConfigFile(digester, path);         }            getServletContext().setAttribute(             Globals.MODULE_KEY + config.getPrefix(),             config);            // Force creation and registration of DynaActionFormClass instances         // for all dynamic form beans we wil be using         FormBeanConfig fbs[] = config.findFormBeanConfigs();         for (int i = 0; i < fbs.length; i++) {             if (fbs[i].getDynamic()) {                 fbs[i].getDynaActionFormClass();             }         }            return config;     }   

 

三.createModuleConfig()方法
那麼初始化配置模組createModuleConfig方法到底做了什麼呢。
其實是產生了一個ModuleConfig的對象。這個對象是由其工廠產生的,由什麼樣的工廠就會產生什麼樣的產品。所以如果是使用者配置過的工廠,那麼就會產生其對應的配置模組的實現。
預設的情況:
代碼 public class DefaultModuleConfigFactory extends ModuleConfigFactory implements Serializable{        // --------------------------------------------------------- Public Methods           /**        * Create and return a newly instansiated {@link ModuleConfig}.        * This method must be implemented by concrete subclasses.        *        * @param prefix Module prefix for Configuration        */       public ModuleConfig createModuleConfig(String prefix) {               return new ModuleConfigImpl(prefix);           }    }  
它的createModuleConfig(String prefix)方法會產生一個ModuleConfigImpl類。

 

四.ModuleConfigImpl類
ModuleConfigImpl類相當於一個JavaBean,用來存放一個web模組運行時所需要的配置資訊。當 然,一個web模組可以擁有多個ModuleConfig,但是預設的是prefix長度為0的ModuleConifg。它 的每個屬性幾乎都是由HashMap組成的,它通過一個configured布爾值來描述當前的ModuleConfig是否已經被初始化完畢,在每存放一個屬性的時候都會監測這個值。如果初始化完畢而還要改變裡面的屬性值,則會報出IllegalStateException("Configuration is frozen")異常,
現在對它的屬性簡單說明如下:
代碼 // 這個HashMap用來儲存ActionConfig對象。    protected HashMap actionConfigs:    //HashMap用來儲存DataSourceConfig對象。    protected HashMap dataSources    //這個HashMap用來儲存ExceptionConfig對象。    protected HashMap exceptions    //這個HashMap用來儲存FormBeanConfig對象。     protected HashMap formBeans    //這個HashMap用來儲存ForwardConfig對象。     protected HashMap forwards    //這個HashMap用來儲存MessageResourcesConfig對象。      protected HashMap messageResources    //這個HashMap用來儲存PlugInConfig對象。       protected ArrayList plugIns    //ControllerConfig類      protected ControllerConfig controllerConfig    //標誌這個ModuleConfig是(true)否(false)配置完成。        protected boolean configured    //用來標誌和區分ModuleConfig類,同時在使用上面的config類初始化相應的資源以後,也是通過這個prefix來區分所屬的不同的web模組。      protected String prefix    //ActionMapping類名,預設為org.apache.struts.action.ActionMapping。[      protected String actionMappingClass = "org.apache.struts.action.ActionMapping"  

 

ModuleConfigImpl類的ModuleConfigImpl方法如下
代碼 public ModuleConfigImpl(String prefix) {          super();          this.prefix = prefix;          this.actionConfigs = new HashMap();          this.actionConfigList = new ArrayList();          this.actionFormBeanClass = "org.apache.struts.action.ActionFormBean";          this.actionMappingClass = "org.apache.struts.action.ActionMapping";          this.actionForwardClass = "org.apache.struts.action.ActionForward";          this.configured = false;          this.controllerConfig = null;          this.dataSources = new HashMap();          this.exceptions = new HashMap();          this.formBeans = new HashMap();          this.forwards = new HashMap();          this.messageResources = new HashMap();          this.plugIns = new ArrayList();      }  
通過其預設工廠的實現,我們可以看到,其執行個體化了一個ModuleConfigImpl的對象,這是ModuleConfig的一種實現,也是當前struts的預設的實現。

 

這是初始化過程開始逐漸明朗.
調用過程factoryObject.createModuleConfig(prefix)--->DefaultModuleConfigFactory 的createModuleConfig(prefix)---->new ModuleConfigImpl(prefix),但好像還有一個問題,ModuleConfigImpl類的ModuleConfigImpl方法裡對其屬性都是new的,沒賦值啊?後來仔細看了半天,發現在initModuleConfig方法裡還有幾行代碼
代碼 .......     Digester digester = initConfigDigester();    .......    igester.push(config);     .......     this.parseModuleConfigFile(digester, path);    .....   
應該是digster攜帶config執行個體在parseModuleConfigFile方法裡初始化好了.

 

五.UserModuleConfigFactory
如果是使用者配置了實現工廠的話,可能的實現就是:
代碼 public class UserModuleConfigFactory extends ModuleConfigFactory implements Serializable{           public ModuleConfig createModuleConfig(String prefix) {            return new ModuleConfigUserImpl(prefix);        }    }  
當然,如果要啟用你的工廠的話,那麼還要在你的設定檔中添加如下部分,在web.xml中修改如下部分:
代碼 <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>3</param-value>       </init-param>       <init-param>         <param-name>detail</param-name>         <param-value>3</param-value>   </init-param>          <init-param>         <param-name>configFactory</param-name>         <param-value>org.aa.struts. UserModuleConfigFactory </param-value>   </init-param>          <load-on-startup>0</load-on-startup>     </servlet>  
這樣的話,你的工廠就可以生效了,也可以產生你自己的配置模組的執行個體了。

 

到此,配置模組MoudelConfig的初始化也已經完成.  

聯繫我們

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