修改:wm5开机启动程序

来源:互联网 发布:效果器软件 编辑:程序博客网 时间:2024/05/16 08:57

Struts源码学习 — ActionServlet的初始化

关键字: struts actionservlet

Struts版本:1.2.9

ActionServlet的初始化由org.apache.struts.action.ActionServlet类的init()方法实现,代码如下:

  1. /**  
  2.  * Initialize this servlet.  Most of the processing has been factored into  
  3.  * support methods so that you can override particular functionality at a  
  4.  * fairly granular level. 
  5.  *  
  6.  * @exception ServletException if we cannot configure ourselves correctly  
  7.  */  
  8. public void init() throws ServletException {   
  9.   
  10.     // Wraps the entire initialization in a try/catch to better handle   
  11.     // unexpected exceptions and errors to provide better feedback   
  12.     // to the developer   
  13.     try {   
  14.         initInternal();   
  15.         initOther();   
  16.         initServlet();   
  17.   
  18.         getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);   
  19.         initModuleConfigFactory();   
  20.         // Initialize modules as needed   
  21.         ModuleConfig moduleConfig = initModuleConfig("", config);   
  22.         initModuleMessageResources(moduleConfig);   
  23.         initModuleDataSources(moduleConfig);   
  24.         initModulePlugIns(moduleConfig);   
  25.         moduleConfig.freeze();   
  26.   
  27.         Enumeration names = getServletConfig().getInitParameterNames();   
  28.         while (names.hasMoreElements()) {   
  29.             String name = (String) names.nextElement();   
  30.             if (!name.startsWith("config/")) {   
  31.                 continue;   
  32.             }   
  33.             String prefix = name.substring(6);   
  34.             moduleConfig = initModuleConfig   
  35.                 (prefix, getServletConfig().getInitParameter(name));   
  36.             initModuleMessageResources(moduleConfig);   
  37.             initModuleDataSources(moduleConfig);   
  38.             initModulePlugIns(moduleConfig);   
  39.             moduleConfig.freeze();   
  40.         }   
  41.   
  42.         this.initModulePrefixes(this.getServletContext());   
  43.   
  44.         this.destroyConfigDigester();   
  45.     } catch (UnavailableException ex) {   
  46.         throw ex;   
  47.     } catch (Throwable t) {   
  48.   
  49.         // The follow error message is not retrieved from internal message   
  50.         // resources as they may not have been able to have been    
  51.         // initialized   
  52.         log.error("Unable to initialize Struts ActionServlet due to an "  
  53.             + "unexpected exception or error thrown, so marking the "  
  54.             + "servlet as unavailable.  Most likely, this is due to an "  
  55.             + "incorrect or missing library dependency.", t);   
  56.         throw new UnavailableException(t.getMessage());   
  57.     }       
  58. }  

看起来代码行数不多,大部分都是对另外方法的调用,其中有些方法挖开比较简单,而有些很繁琐,为了避免这篇文章过长,对于比较繁琐的方法调用我会另开文章来说。

 

  1. initInternal();  

该方法初始化Struts的内部资源文件,该文件路径由ActionServlet的internalName字段指定,默认值是org.apache.struts.action.ActionResources,即Struts的JAR包里的org/apache/struts.action.ActionResources.properties及其国际化版本文件。该文件给出了一些应用运行时,由Struts产生的信息,包括一些异常报错信息,从这里可以看出,我们完全可以让Struts自身抛出的异常信息中文化。

 

  1. initOther();  

该方法做了3件事:

如果web.xml里ActionServlet的配置中给出了config初始化参数,将该参数的值赋给ActionServlet的config字段;

如果web.xml里ActionServlet的配置中给出了convertNull初始化参数,如果该参数值是true、yes、on、y、1中的一个,将ActionServlet的convertNull字段设为true;

如果ActionServlet的convertNull字段值为true,则覆盖Apache Commons BeanUtils中几个基本数据类型包装类的转换器的默认实现,使当转换数据类型失败时,返回null,默认的实现是返回非null值。关于Struts使用的数据类型转换器

 

  1. initServlet();  

这个方法挖开后行数不算少,但其主要作用总结就一句话:将web.xml里ActionServlet配置中的url-pattern的值赋给ActionServlet类的servletMapping字段。实现方式是用Apache Commons Digester解析web.xml,用Digester内置的CallMethodRule和CallParamRule使web.xml被解析时,自动调用ActionServlet类的addServletMapping(String servletName, String urlPattern)方法。

 

  1. getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);  

将ActionServlet实例设置为ServletContext的一个属性。

 

  1. initModuleConfigFactory();  

如果web.xml里ActionServlet配置中给出了configFactory初始化参数,将其值指定的类做为Struts的ModuleConfigFactory,该值应该是一个完全限定类名,Struts默认ModuleConfigFactory的实现是org.apache.struts.config.impl.DefaultModuleConfigFactory。

 

  1. // Initialize modules as needed   
  2. ModuleConfig moduleConfig = initModuleConfig("", config);   
  3. initModuleMessageResources(moduleConfig);   
  4. initModuleDataSources(moduleConfig);   
  5. initModulePlugIns(moduleConfig);   
  6. moduleConfig.freeze();   
  7.   
  8. Enumeration names = getServletConfig().getInitParameterNames();   
  9. while (names.hasMoreElements()) {   
  10.     String name = (String) names.nextElement();   
  11.     if (!name.startsWith("config/")) {   
  12.         continue;   
  13.     }   
  14.     String prefix = name.substring(6);   
  15.     moduleConfig = initModuleConfig   
  16.         (prefix, getServletConfig().getInitParameter(name));   
  17.     initModuleMessageResources(moduleConfig);   
  18.     initModuleDataSources(moduleConfig);   
  19.     initModulePlugIns(moduleConfig);   
  20.     moduleConfig.freeze();   
  21. }  

把这段代码放到一起说,是因为它们做的是同一件事,只是操作的对象不同。

从代码上很容易看出,while循环外和内的代码做的是同一件事,简单说就是将web.xml里给出的Struts配置文件初始化为ModuleConfig对象,将Struts配置文件里给出的MessageResource、DataSource、PlugIn也都初始化为对象,然后将这些对象都放到ServletContext里。

不同的是,while循环外操作的是web.xml里ActionServlet配置中config初始化参数指定的Struts配置文件;while循环内操作的是web.xml里ActionServlet配置中以"config/"开头的初始化参数指定的Struts配置文件。

while循环外的代码执行完后,会产生一个默认的没有前缀的ModuleConfig对象放到ServletContext里;while循环内的代码执行完后,会产生N个有前缀的ModuleConfig对象放到ServletContext里,N等于web.xml里ActionServlet配置中以"config/"开头的初始化参数的个数,它们的前缀是"config/"后的字符串。这个前缀体现在访问应用的URL中,用来区分各模块,方便团队开发。初始化ModuleConfig详解

 

  1. this.initModulePrefixes(this.getServletContext());  

将上面while循环内产生的所有前缀生成一个String数组,放到ServletContext里。

 

  1. this.destroyConfigDigester();  

将ActionServlet类的configDigester字段重置为null。