Struts 源码学习之ActionServlet (四)
Ⅳ
/* 循环struts 配置文件(用"," 分开的多个struts 配置文件)并解析, parseModuleConfigFile 执行之后可以 从struts-config.xml 等配置文件中得到 Ⅱ 中 actionConfigs/actionConfigList 、exceptions 、formBeans 、forwards 、messageResources 、plugIns 等的配置,并把得到的所有值封装到对象 ModuleConfig 对象(config) 中 */
List urls = splitAndResolvePaths(paths);
URL url;
for (Iterator i = urls.iterator(); i.hasNext();) {
url = (URL) i.next();
digester.push(config);
this.parseModuleConfigFile (digester, url);
}
Ⅴ
// 把config 存储到servletContext 中 ,属性名为Globals.MODULE_KEY
( " org.apache.struts.action.MODULE " )
getServletContext().setAttribute(Globals.MODULE_KEY
+ config.getPrefix(), config);
⑥ 用户资源文件的初始化 initModuleMessageResources(moduleConfig);
在上面第⑤ 步的Ⅱ 中我们已经创建了ModuleConfig 对象 并在Ⅲ 和Ⅵ 中从struts-config.xml 等配置文件中得到 得到一些配置且封装到ModuleConfig 对象 中,所以在下面可以直接使用initModuleMessageResources(moduleConfig);
initModuleMessageResources(moduleConfig); 所做的工作:
⑴
/* 从moduleConfig 中读取所有的资源文件(包括 ① 内部资源文件 和 ⑤ 中Ⅵ 利用Digester 读取的struts 配置文件指定的用户资源文件) */
MessageResourcesConfig[] mrcs = config.findMessageResourcesConfigs();
注: 此时moduleConfig 中默认只含有① 内部资源文件 ActionResources.properties
⑵
// 把resources (包括 ① 内部资源文件 和 ⑥ 用户资源文件 )存储到servletContext 中 // 属性名为mrcs[i].getKey() + config.getPrefix()
for (int i = 0; i < mrcs.length; i++) {
if ((mrcs[i].getFactory() == null)
|| (mrcs[i].getParameter() == null)) {
continue;
}
if (log.isDebugEnabled()) {
log.debug("Initializing module path '" + config.getPrefix()
+ "' message resources from '" + mrcs[i].getParameter()
+ "'");
}
String factory = mrcs[i].getFactory();
MessageResourcesFactory.setFactoryClass(factory);
MessageResourcesFactory factoryObject =
MessageResourcesFactory.createFactory();
factoryObject.setConfig(mrcs[i]);
MessageResources resources =
factoryObject.createResources(mrcs[i].getParameter());
resources.setReturnNull(mrcs[i].getNull());
resources.setEscape(mrcs[i].isEscape());
getServletContext().setAttribute(mrcs[i].getKey()
+ config.getPrefix(), resources);
}
⑦ 用户插件的初始化 initModulePlugIns(moduleConfig);
在上面第⑤ 步的Ⅱ 中我们已经创建了ModuleConfig 对象 并在Ⅲ 和Ⅵ 中从struts-config.xml 等配置文件中得到 得到一些配置且封装到ModuleConfig 对象 中,所以在下面可以直接使用initModulePlugIns(ModuleConfig config);
initModulePlugIns(moduleConfig); 所做的工作:
⑴
// 从moduleConfig 中读取所有的插件文件
PlugInConfig[] plugInConfigs = config.findPlugInConfigs();
PlugIn[] plugIns = new PlugIn[plugInConfigs.length];
⑵
// 把所有plugIns 存储到servletContext 中
// 属性名为Globals.PLUG_INS_KEY + config.getPrefix()
.......
getServletContext().setAttribute(Globals.PLUG_INS_KEY
+ config.getPrefix(), plugIns);
.......
⑧ 把struts 配置文件中的其他配置 存储到servletContext 中 ,包括
initModuleFormBeans(moduleConfig);
initModuleForwards(moduleConfig);
initModuleExceptionConfigs(moduleConfig);
initModuleActions(moduleConfig);
⑨ 调用 moduleConfig.freeze(); 固定组件配置
/* 使ModuleConfig 中的 actionConfigs/actionConfigList 、exceptions 、formBeans 、forwards 、messageResources 、plugIns 等的配置等变得不可改变 */
moduleConfig.freeze();
⑩ 解析以"config/" 开头的其他struts 配置文件
// 遍历web.xml 中servletConfig 配置的 initParameterNames
// 如发现以" config/ " 开始的parameter ,则根据此值初始化其它的ModuleConfig
Enumeration names = getServletConfig().getInitParameterNames();
while (names.hasMoreElements()) {
String name = (String) names.nextElement();
if (!name.startsWith(configPrefix)) {
continue;
}
String prefix = name.substring(configPrefixLength);
moduleConfig =
initModuleConfig(prefix,
getServletConfig().getInitParameter(name));
initModuleMessageResources(moduleConfig);
initModulePlugIns(moduleConfig);
initModuleFormBeans(moduleConfig);
initModuleForwards(moduleConfig);
initModuleExceptionConfigs(moduleConfig);
initModuleActions(moduleConfig);
moduleConfig.freeze();
}
<servlet>
<servlet-name >action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name> <!-- 得到"config" 参数-->
<param-value>/WEB-INF/struts-config.xml</param-value>
</init-param>
<init-param>
<param-name>config/admin </param-name> <!-- 得到"config/admin" 参数-->
<param-value>/WEB-INF/struts-config-admin.xml</param-value>
</init-param>
.......
</servlet>
在⑩ 解析以"config/" 开头的其他struts 配置文件 之后ActionServlet 的init() 方法还需要做
⑴
// 初始化其他模块的前缀
this.initModulePrefixes(this.getServletContext());
initModulePrefixes(this.getServletContext()); 所做的工作:
/* 把其他模块prefixes 存储到servletContext 中,属性名为
Globals.MODULE_PREFIXES_KEY ( " org.apache.struts.globals.MODULE_PREFIXES " ) */
context.setAttribute(Globals.MODULE_PREFIXES_KEY, prefixes);
⑵
// 设置configDigester = null ,释放内存
this.destroyConfigDigester();
至此struts 的核心类ActionServlet 的init() 方法完成servlet 的初始化工作