您的位置:首页 > 其它

修改:wm5开机启动程序

2008-01-25 09:54 309 查看

Struts源码学习 — ActionServlet的初始化

关键字: struts actionservlet

Struts版本:1.2.9

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

/**

* Initialize this servlet. Most of the processing has been factored into

* support methods so that you can override particular functionality at a

* fairly granular level.

*

* @exception ServletException if we cannot configure ourselves correctly

*/

public void init() throws ServletException {

// Wraps the entire initialization in a try/catch to better handle

// unexpected exceptions and errors to provide better feedback

// to the developer

try {

initInternal();

initOther();

initServlet();

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

initModuleConfigFactory();

// Initialize modules as needed

ModuleConfig moduleConfig = initModuleConfig("", config);

initModuleMessageResources(moduleConfig);

initModuleDataSources(moduleConfig);

initModulePlugIns(moduleConfig);

moduleConfig.freeze();

Enumeration names = getServletConfig().getInitParameterNames();

while (names.hasMoreElements()) {

String name = (String) names.nextElement();

if (!name.startsWith("config/")) {

continue;

}

String prefix = name.substring(6);

moduleConfig = initModuleConfig

(prefix, getServletConfig().getInitParameter(name));

initModuleMessageResources(moduleConfig);

initModuleDataSources(moduleConfig);

initModulePlugIns(moduleConfig);

moduleConfig.freeze();

}

this.initModulePrefixes(this.getServletContext());

this.destroyConfigDigester();

} catch (UnavailableException ex) {

throw ex;

} catch (Throwable t) {

// The follow error message is not retrieved from internal message

// resources as they may not have been able to have been

// initialized

log.error("Unable to initialize Struts ActionServlet due to an "

+ "unexpected exception or error thrown, so marking the "

+ "servlet as unavailable. Most likely, this is due to an "

+ "incorrect or missing library dependency.", t);

throw new UnavailableException(t.getMessage());

}

}

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

initInternal();

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

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使用的数据类型转换器

initServlet();

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

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

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

initModuleConfigFactory();

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

// Initialize modules as needed

ModuleConfig moduleConfig = initModuleConfig("", config);

initModuleMessageResources(moduleConfig);

initModuleDataSources(moduleConfig);

initModulePlugIns(moduleConfig);

moduleConfig.freeze();

Enumeration names = getServletConfig().getInitParameterNames();

while (names.hasMoreElements()) {

String name = (String) names.nextElement();

if (!name.startsWith("config/")) {

continue;

}

String prefix = name.substring(6);

moduleConfig = initModuleConfig

(prefix, getServletConfig().getInitParameter(name));

initModuleMessageResources(moduleConfig);

initModuleDataSources(moduleConfig);

initModulePlugIns(moduleConfig);

moduleConfig.freeze();

}

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

从代码上很容易看出,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详解

this.initModulePrefixes(this.getServletContext());

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

this.destroyConfigDigester();

将ActionServlet类的configDigester字段重置为null。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: