`
chenchao051
  • 浏览: 137573 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Struts配置模块MoudelConfig初始化的实现

阅读更多

Struts配置模块MoudelConfig初始化的实现

   上回说到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的初始化也已经完成.
分享到:
评论

相关推荐

    探讨Struts的初始化方法

    Struts框架通过其核心组件`ActionServlet`的初始化过程实现了对整个应用环境的配置和准备。其中,`MessageResources`的生成和配置是确保应用支持多语言和国际化的关键环节。理解这些初始化细节有助于开发者更好地...

    struts2 模块包含

    通过在Action配置中声明不同的拦截器栈,可以实现不同模块的定制化处理。 3. **Result结果**:Action执行后的结果通常会跳转到一个JSP页面或者另一个Action。Result配置允许开发者为每个Action指定多种可能的结果,...

    struts 实现模块化

    在Struts中实现模块化,可以帮助开发者更有效地组织和管理应用程序的不同部分。 在Struts框架中,模块化主要通过Action配置和Struts.xml文件来实现。每个模块可以视为独立的功能单元,拥有自己的Action类、配置文件...

    struts多模块配制

    9. **部署描述符**:在web.xml中,需要配置Struts的过滤器(例如`&lt;filter-name&gt;struts2&lt;/filter-name&gt;`),并指定其加载的初始化参数,如配置文件的位置,以确保框架能够找到并加载所有的模块配置。 10. **测试与...

    struts2初始使用环境配置

    以下将详细介绍Struts2的初始使用环境配置步骤。 首先,确保你已经安装了Java Development Kit (JDK)。JDK是开发Java应用的基础,你需要至少JDK 1.6或以上版本来支持Struts2。下载并安装JDK后,设置好系统环境变量`...

    struts多模块.pdf

    2. **通知控制器**:在`web.xml`中,我们需要为`ActionServlet`添加相应的初始化参数,告知它每个模块的配置文件位置。例如: ``` &lt;param-name&gt;config &lt;param-value&gt;/WEB-INF/struts-config.xml ...

    论坛系统项目(Struts 2+Hibernate+Spring实现)

    论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts 2+Hibernate+Spring实现)论坛系统项目(Struts...

    Struts多模块[定义].pdf

    2. **通知控制器**:为了让Struts控制器(ActionServlet)知道所有模块的存在,需要在`web.xml`中为每个模块的配置文件设置初始化参数。例如,除了默认模块外,每个模块的配置文件路径作为`ActionServlet`的初始化...

    struts1多模块多配置文件

    4. **修改web.xml添加模块配置文件路径**: - 在web.xml文件中,通过`&lt;param-value&gt;`元素指定每个模块对应的配置文件路径。例如: ```xml &lt;param-name&gt;config &lt;param-value&gt;/WEB-INF/struts-config-user.xml,/...

    多个struts配置文件使用

    在`web.xml`文件中,可以通过`ActionServlet`的初始化参数`config`来指定一个或多个配置文件的位置。例如: ```xml &lt;servlet-name&gt;action &lt;servlet-class&gt;org.apache.struts.action.ActionServlet ...

    Struts配置文件详解

    Struts配置文件是Struts框架的灵魂所在,它不仅控制着框架的初始化流程,还决定着组件的创建与配置,极大提升了应用的灵活性与可扩展性。 **1.1 动态配置提升灵活性** Struts配置文件允许开发者在不修改代码的情况...

    struts的模块话开发

    - 模块配置:每个模块可以包含自己的Action、结果类型、拦截器等配置,确保各个模块间的相互独立。 2. **Action与ActionMapping**: - Action:模块中的核心组件,负责处理用户请求,执行业务逻辑,并返回一个...

    Struts配置文件详解.

    此外,`ConfigRuleSet`类负责解析配置文件,根据预定义的规则创建并初始化其他配置类的实例。 2. `&lt;struts-config&gt;`元素 `&lt;struts-config&gt;`是配置文件的根元素,对应于`ModuleConfig`类。它包含8个主要子元素,如`...

    Struts模块化编程教程 .doc

    - **元素`controller`**: 描述了Struts模块运行环境的配置信息,包括ActionServlet的初始化参数等。 - **元素`data-source`**: 描述了数据源的配置信息,用于数据库访问。 #### 四、总结 通过以上介绍,我们可以...

    struts2采用convention-plugin实现零配置

    然而,随着版本的更新,Struts2引入了一个名为Convention Plugin的新特性,旨在简化配置过程,实现所谓的“零配置”开发。 **什么是Struts2 Convention Plugin?** Convention Plugin是Struts2的一个插件,它基于...

    struts2登录注册简单实现

    总的来说,这个“struts2登录注册简单实现”项目涵盖了Struts2框架的基础应用,包括Action的创建、配置文件的编写、视图设计、数据处理以及安全性考虑等多个方面。通过实践,开发者能更深入地理解Struts2的架构和...

    Java进阶Struts多模块的技巧.rar

    通过在web.xml中配置多个Struts2的FilterDispatcher,我们可以将不同模块的请求分发到相应的模块配置文件,实现多模块的隔离。 接着,我们探讨如何创建Struts多模块项目。通常,项目结构可以分为以下几个部分: 1....

    struts 配置

    在Struts中,`web.xml`负责初始化Struts的`ActionServlet`以及配置其他关键组件。 1. `&lt;servlet&gt;`与`servlet-mapping`:首先,我们需要定义Struts的`ActionServlet`,它是整个框架的核心,处理所有的HTTP请求。`...

    Struts配置文件详解.pdf

    例如,`org.apache.struts.config.ModuleConfig`类用于表示整个模块的配置信息;而其他的类则针对特定的配置元素,如`FormBeanConfig`类对应`&lt;form-bean&gt;`元素等。 ##### 3. Struts配置文件的读取过程 当Struts...

    struts2配置文件加载顺序

    5. **package配置文件**:除了`struts.xml`外,开发者还可以创建多个包(package)配置文件,以实现模块化的配置。这些文件可以放在`struts.xml`中引入,也可以通过`&lt;include file="..."/&gt;`标签进行引入。 加载顺序...

Global site tag (gtag.js) - Google Analytics