`

MoudleConfig初始化的实现

阅读更多
上回说到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采用了这样的工厂方法
一个接口:ModuleConfig.java
一个抽象类:ModuleConfigFactory.java
一个ModuleConfig的实现类:ModuleConfigImpl.java
一个ModuleConfigFactory的子类:DefaultModuleConfigFactory.java

具体介绍
一.initModuleConfigFactory()
在ActionServlet初始化ModuleConfig的时候,先要初始化配置工厂,
Java代码 复制代码
  1. initModuleConfigFactory();  
initModuleConfigFactory();


那么这个工厂到底初始化了什么?
现看源代码:
Java代码 复制代码
  1. protected void initModuleConfigFactory(){   
  2.         String configFactory = getServletConfig().getInitParameter("configFactory");   
  3.         if (configFactory != null) {   
  4.             ModuleConfigFactory.setFactoryClass(configFactory);   
  5.         }   
  6. }  
protected void initModuleConfigFactory(){
        String configFactory = getServletConfig().getInitParameter("configFactory");
        if (configFactory != null) {
            ModuleConfigFactory.setFactoryClass(configFactory);
        }
}

很明显,现从配置参数取得其配置,如果用户没有作配置,那么就使用默认配置,如果用户作了配置,那么就使用用户的配置。
如果用户作了配置的话,那么就执行设置成用户的工厂。如何设置的呢?
Java代码 复制代码
  1. public static void setFactoryClass(String factoryClass) {   
  2.     ModuleConfigFactory.factoryClass = factoryClass;   
  3.     ModuleConfigFactory.clazz = null;   
  4. }  
    public static void setFactoryClass(String factoryClass) {
        ModuleConfigFactory.factoryClass = factoryClass;
        ModuleConfigFactory.clazz = null;
    }

直接给ModuleConfigFactory.factoryClass赋值,因为此变量是一个静态的变量:
   
Java代码 复制代码
  1. protected static String factoryClass =   
  2.         "org.apache.struts.config.impl.DefaultModuleConfigFactory";  
protected static String factoryClass =
        "org.apache.struts.config.impl.DefaultModuleConfigFactory";

由此定义决定了可以使用此赋值方法。正是因为此变量是一个静态的变量,所以在下面的得工厂生成对象的时候就可以创建一个用户自己的对象。

二.initModuleConfig()
之后由配置工厂再实例化一个ModuleConfig的对象。
Java代码 复制代码
  1. ModuleConfig moduleConfig = initModuleConfig("", config);  
ModuleConfig moduleConfig = initModuleConfig("", config);


看一下initModuleConfig方法是如何初始化ModuleConfig的,看下面的源代码:
Java代码 复制代码
  1. protected ModuleConfig initModuleConfig(String prefix, String paths)   
  2.      throws ServletException {   
  3.  //这个地方,我们可以看到,此时就由ModuleConfigFactory直接创建了一个工厂对象,而此时我们用的配置就是上面我们初始化后的配置。如果用户自己做了配置,那么此时初始化的工厂就是用户指定后的工厂。如果没有的话,那么就初始化的时默认的工厂。   
  4. DefaultModuleConfigFactory的一个实例   
  5.         ModuleConfigFactory factoryObject = ModuleConfigFactory.createFactory();   
  6.      ModuleConfig config = factoryObject.createModuleConfig(prefix);   
  7.      // Configure the Digester instance we will use   
  8.      Digester digester = initConfigDigester();   
  9.   
  10.      // Process each specified resource path   
  11.      while (paths.length() > 0) {   
  12.          digester.push(config);   
  13.          String path = null;   
  14.          int comma = paths.indexOf(',');   
  15.          if (comma >= 0) {   
  16.              path = paths.substring(0, comma).trim();   
  17.              paths = paths.substring(comma + 1);   
  18.          } else {   
  19.              path = paths.trim();   
  20.              paths = "";   
  21.          }   
  22.   
  23.          if (path.length() < 1) {   
  24.              break;   
  25.          }   
  26.   
  27.          this.parseModuleConfigFile(digester, path);   
  28.      }   
  29.   
  30.      getServletContext().setAttribute(   
  31.          Globals.MODULE_KEY + config.getPrefix(),   
  32.          config);   
  33.   
  34.      // Force creation and registration of DynaActionFormClass instances   
  35.      // for all dynamic form beans we wil be using   
  36.      FormBeanConfig fbs[] = config.findFormBeanConfigs();   
  37.      for (int i = 0; i < fbs.length; i++) {   
  38.          if (fbs[i].getDynamic()) {   
  39.              fbs[i].getDynaActionFormClass();   
  40.          }   
  41.      }   
  42.   
  43.      return config;   
  44.  }  
   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的对象。这个对象是由其工厂产生的,由什么样的工厂就会生成什么样的产品。所以如果是用户配置过的工厂,那么就会生成其对应的配置模块的实现。
默认的情况:
Java代码 复制代码
  1. public class DefaultModuleConfigFactory extends ModuleConfigFactory implements Serializable{   
  2.     // --------------------------------------------------------- Public Methods   
  3.   
  4.     /**  
  5.      * Create and return a newly instansiated {@link ModuleConfig}.  
  6.      * This method must be implemented by concrete subclasses.  
  7.      *  
  8.      * @param prefix Module prefix for Configuration  
  9.      */  
  10.     public ModuleConfig createModuleConfig(String prefix) {   
  11.   
  12.         return new ModuleConfigImpl(prefix);   
  13.   
  14.     }   
  15. }  
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")异常,
现在对它的属性简单说明如下:
     
Java代码 复制代码
  1. // 这个HashMap用来存储ActionConfig对象。   
  2. protected HashMap actionConfigs:   
  3. //HashMap用来存储DataSourceConfig对象。   
  4. protected HashMap dataSources   
  5. //这个HashMap用来存储ExceptionConfig对象。   
  6. protected HashMap exceptions   
  7. //这个HashMap用来存储FormBeanConfig对象。   
  8.  protected HashMap formBeans   
  9. //这个HashMap用来存储ForwardConfig对象。   
  10.  protected HashMap forwards   
  11. //这个HashMap用来存储MessageResourcesConfig对象。   
  12.   protected HashMap messageResources   
  13. //这个HashMap用来存储PlugInConfig对象。   
  14.    protected ArrayList plugIns   
  15. //ControllerConfig类   
  16.   protected ControllerConfig controllerConfig   
  17. //标志这个ModuleConfig是(true)否(false)配置完成。   
  18.     protected boolean configured   
  19. //用来标志和区分ModuleConfig类,同时在使用上面的config类初始化相应的资源以后,也是通过这个prefix来区分所属的不同的web模块。   
  20.   protected String prefix   
  21. //ActionMapping类名,缺省为org.apache.struts.action.ActionMapping。[   
  22.   protected String actionMappingClass = "org.apache.struts.action.ActionMapping"  
// 这个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方法如下
Java代码 复制代码
  1. public ModuleConfigImpl(String prefix) {   
  2.       super();   
  3.       this.prefix = prefix;   
  4.       this.actionConfigs = new HashMap();   
  5.       this.actionConfigList = new ArrayList();   
  6.       this.actionFormBeanClass = "org.apache.struts.action.ActionFormBean";   
  7.       this.actionMappingClass = "org.apache.struts.action.ActionMapping";   
  8.       this.actionForwardClass = "org.apache.struts.action.ActionForward";   
  9.       this.configured = false;   
  10.       this.controllerConfig = null;   
  11.       this.dataSources = new HashMap();   
  12.       this.exceptions = new HashMap();   
  13.       this.formBeans = new HashMap();   
  14.       this.forwards = new HashMap();   
  15.       this.messageResources = new HashMap();   
  16.       this.plugIns = new ArrayList();   
  17.   }  
  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方法里还有几行代码
Java代码 复制代码
  1. .......   
  2.  Digester digester = initConfigDigester();   
  3. .......   
  4. igester.push(config);   
  5.  .......   
  6.  this.parseModuleConfigFile(digester, path);   
  7. .....  
  .......
   Digester digester = initConfigDigester();
  .......
 digester.push(config);
   .......
   this.parseModuleConfigFile(digester, path);
  .....

应该是digster携带config实例在parseModuleConfigFile方法里初始化好了.

五.UserModuleConfigFactory
如果是用户配置了实现工厂的话,可能的实现就是:
Java代码 复制代码
  1. public class UserModuleConfigFactory extends ModuleConfigFactory implements Serializable{   
  2.        public ModuleConfig createModuleConfig(String prefix) {   
  3.         return new ModuleConfigUserImpl(prefix);   
  4.     }   
  5. }  
public class UserModuleConfigFactory extends ModuleConfigFactory implements Serializable{
       public ModuleConfig createModuleConfig(String prefix) {
        return new ModuleConfigUserImpl(prefix);
    }
}

    当然,如果要启用你的工厂的话,那么还要在你的配置文件中添加如下部分,在web.xml中修改如下部分:
Java代码 复制代码
  1. <servlet>   
  2.     <servlet-name>action</servlet-name>   
  3.     <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>   
  4.     <init-param>   
  5.       <param-name>config</param-name>   
  6.       <param-value>/WEB-INF/struts-config.xml</param-value>   
  7.     </init-param>   
  8.     <init-param>   
  9.       <param-name>debug</param-name>   
  10.       <param-value>3</param-value>   
  11.     </init-param>   
  12.     <init-param>   
  13.       <param-name>detail</param-name>   
  14.       <param-value>3</param-value>   
  15. </init-param>   
  16.   
  17.     <init-param>   
  18.       <param-name>configFactory</param-name>   
  19.       <param-value>org.aa.struts. UserModuleConfigFactory </param-value>   
  20. </init-param>   
  21.   
  22.     <load-on-startup>0</load-on-startup>   
  23.   </servlet>  
<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的初始化也已经完成.
分享到:
评论

相关推荐

    SIN初始化_混沌初始化_matlab_混沌映射_种群初始化_sin映射初始化粒子群_

    通过混沌映射初始化的粒子群,可以期望在搜索空间中实现更有效的探索,尤其是在解决多模态优化问题时,混沌映射的特性可以帮助粒子避开局部极小值,从而提高全局收敛性能。然而,需要注意的是,混沌映射的参数选择...

    C++全局变量初始化的一点总结

    静态初始化发生在程序加载时,主要针对那些可以用常量表达的初始化,例如零初始化(zero initialization)和常量初始化(const initialization)。零初始化的变量通常存放在BSS段,而常量初始化的变量则位于数据段,...

    C++构造函数初始化列表

    ### C++构造函数初始化列表详解 在C++编程语言中,构造函数是对象生命周期开始时自动调用的特殊成员函数,用于初始化对象的状态。构造函数初始化列表是C++中一个非常重要的特性,它允许程序员在对象创建时直接对类...

    比赛工程2,初始化上行至10层;电梯PLC;好像是六部十层;;

    比赛工程2,初始化上行至10层;电梯PLC;好像是六部十层;;比赛工程2,初始化上行至10层;电梯PLC;好像是六部十层;;比赛工程2,初始化上行至10层;电梯PLC;好像是六部十层;;比赛工程2,初始化上行至10层;电梯PLC...

    Revit+外部工具+无法初始化附加模块“CollaborateDB”,因为程序集C:\Prog+无法初始化附加模块的解决方法

    Revit外部工具无法初始化附加模块的解决方法 大家在安装完Revit或者卸载后重装Revit时是否遇到外部工具无法初始化附加模块的问题,每次打开不停的弹出对话框,烦得要死。 无法初始化附加模块“CollaborateDB”,...

    CSS样式初始化commonInitialize.css

    CSS样式初始化是开发过程中一个重要的步骤,它旨在消除浏览器之间的默认样式差异,确保网页在不同浏览器上的一致性表现。"commonInitialize.css"就是这样一个专门用于全局CSS样式初始化的文件。 首先,我们来理解...

    DDR 初始化 流程

    ### DDR初始化流程详解 DDR(Double Data Rate)内存技术在现代计算系统中扮演着至关重要的角色,其高速数据传输能力和高带宽特性使得DDR成为服务器、个人计算机以及各种电子设备中的首选内存类型。DDR初始化流程是...

    类继承的初始化顺序类,继承的初始化顺序

    本文详细介绍了类继承中的初始化顺序问题,包括初始化的基本概念、初始化过程中的关键步骤以及如何正确处理基类和子类之间的构造函数调用。理解这些概念对于编写高效、可维护的面向对象程序至关重要。希望通过对这些...

    typedef struct 与 struct 的区别及初始化

    在C/C++编程语言中,`typedef` 和 `struct` 是两种不同的声明结构体类型...而结构体初始化则涉及到成员变量的初始赋值,可以使用初始化列表来实现。在实际编程中,合理使用 `typedef` 可以提高代码的可读性和可维护性。

    ARM初始化文件详解

    本文将深入探讨ARM初始化文件的结构、功能以及在实际应用中的实现。 一、初始化文件的作用 1. 设置处理器状态:初始化文件首先会设置ARM处理器的工作模式,如复位模式、Thumb模式或ARM模式,以及相应的寄存器初始值...

    java代码的初始化顺序demo

    `init`文件可能包含了各种构造函数的实现,展示它们如何被调用以及与初始化块交互的方式。 5. **成员变量初始化**: Java允许我们在变量声明时进行初始化。这种初始化发生在构造函数之前,因此在实例初始化块之前...

    组态王设备初始化失败安装可用

    在工业控制系统中,"设备初始化失败"是一个常见的问题,这可能由多种原因引起,例如驱动程序不兼容、系统设置错误、硬件故障或是缺少必要的组件。在本案例中,提到的“组态王设备初始化失败安装可用”指的是,当遇到...

    解决数码视讯Q5使用USB_Burning_Tool刷机时 提示 初始化DDR/读取初始化结果/USB错误

    解决数码视讯Q5使用USB_Burning_Tool刷机时 提示 初始化DDR/读取初始化结果/USB错误

    usart_stm32五个串口初始化以及发送_

    本文将详细讨论如何对STM32F103的五个串口进行初始化并实现发送功能。 首先,我们来看`usart.c`和`usart.h`这两个文件。在C语言编程中,`.c`文件通常包含了函数的实现,而`.h`文件则定义了相关的函数原型、结构体和...

    Nacos 2.1.2 数据库初始化脚本

    Nacos 2.1.2 数据库初始化脚本

    ic卡m1卡初始化工具32位

    3. **ICCard.dll**:这是另一个与IC卡操作相关的DLL文件,可能包含了处理IC卡数据读取、写入以及初始化的具体实现。 4. **ICCardInit.exe**:这是一个可执行文件,很可能是主应用程序,用户通过这个程序来运行IC卡...

    vue初始化模板vue初始化模板

    vue初始化模板vue初始化模板vue初始化模板vue初始化模板vue初始化模板vue初始化模板vue初始化模板vue初始化模板vue初始化模板vue初始化模板vue初始化模板vue初始化模板vue初始化模板vue初始化模板vue初始化模板vue...

    TIA博途中如何设置不需要初始化DB块也可以进行下载?.docx

    - **无需初始化下载的概念**:介绍在TIA博途(TIA Portal)软件中如何设置以实现无需初始化即可下载修改后的块(DB块),确保正在运行的控制系统不受影响。 - **适用条件与限制**:列出使用“无需重新初始化的下载”功能...

    32. 权重初始化方法1

    具体实现时,权重`W`的初始化可以通过以下公式计算:`W = np.random.randn(shape) * sqrt(2 / (input_size + output_size))`。这个公式考虑了输入和输出的节点数量,有助于平衡网络中前后层的梯度。 最后,我们提到...

    混沌初始化程序

    fortran编写的logistic映射的混沌程序,用于一般智能优化算法的初始化种群。

Global site tag (gtag.js) - Google Analytics