④ 调用 initChain(); 读取web.xml中命令链文件初始值chainConfig
protected String chainConfig = "org/apache/struts/chain/chain-config.xml";
// ④ initChain();
// 如没有chainConfig参数,则使用默认 "org/apache/struts/chain/chain-config.xml"
String value;
value = getServletConfig().getInitParameter("chainConfig");
if (value != null) {
chainConfig = value;
}
ConfigParser parser = new ConfigParser();
List urls = splitAndResolvePaths(chainConfig);
URL resource;
// chainConfig 替换了原来传统的在 RequestProcessor 类中执行的 HTTP 请求处理
for (Iterator i = urls.iterator(); i.hasNext();) {
resource = (URL) i.next();
log.info("Loading chain catalog from " + resource);
parser.parse(resource);
}
/************************************************************
// org.apache.struts.action. RequestProcessor .java 的process方法中,一些方法如
processLocale (request, response);
processContent (request, response);
processNoCache (request, response);
.......
被 "org/apache/struts/chain/chain-config.xml" 中下列配置所取代
<command
className="org.apache.struts.chain.commands.servlet.SelectLocale"/>
<command
className="org.apache.struts.chain.commands.servlet.SetContentType"/>
<command
className="org.apache.struts.chain.commands.servlet.RequestNoCache"/>
.......
好处是充分降低了代码内部方法与方法之间的耦合度
************************************************************/
在④/⑤之间
// 把servlet对象存储到servletContext中,属性名为Globals.ACTION_SERVLET_KEY
( " org.apache.struts.action.ACTION_SERVLET " )
getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);
⑤ 调用 initModuleConfigFactory(); 和 initModuleConfig("", config); 创建 ModuleConfig 对象。Struts中的MessageResource、PlugIn、数据源等,都是通过ModuleConfig来实现的。
// 初始化ModuleConfig配置工厂
initModuleConfigFactory(); // ⑴
// 由配置工厂实例化一个ModuleConfig的对象
ModuleConfig moduleConfig = initModuleConfig("", config); // ⑵
⑴
initModuleConfigFactory(); 所做的工作:
// 得到web.xml中"configFactory"参数,如果找不到,则使用 默认工厂
String configFactory = getServletConfig().getInitParameter("configFactory");
if (configFactory != null) {
ModuleConfigFactory.setFactoryClass(configFactory);
}
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>configFactory</param-name> <!-- 得到"configFactory"参数-->
<param-value>com.lively.base.webapp.UserModuleConfigFactory</param-value>
</init-param>
.......
</servlet>
在ModuleConfigFactory.java中的setFactoryClass方法,
public static void setFactoryClass(String factoryClass) {
ModuleConfigFactory.factoryClass = factoryClass;
ModuleConfigFactory.clazz = null;
}
其中
protected static Class clazz = null;
protected static String factoryClass =
"org.apache.struts.config.impl.DefaultModuleConfigFactory";
⑵
initModuleConfig ("", config); 所做的工作:
// Parse the configuration for this module
ModuleConfigFactory factoryObject = ModuleConfigFactory.createFactory(); // Ⅰ
ModuleConfig config = factoryObject.createModuleConfig(prefix); // Ⅱ
Ⅰ
ModuleConfigFactory.createFactory(); 方法中:
protected static Class clazz = null;
protected static String factoryClass =
"org.apache.struts.config.impl.DefaultModuleConfigFactory";
if (clazz == null) {
clazz = RequestUtils.applicationClass(factoryClass);
}
factory = (ModuleConfigFactory) clazz.newInstance();
而RequestUtils.applicationClass通过classLoader加载一个
org.apache.struts.config.impl.DefaultModuleConfigFactory
Ⅱ
ModuleConfig config = factoryObject.createModuleConfig(prefix); 方法中:
// 通过new ModuleConfigImpl(prefix);设置一些变量的初始值,在 initModuleConfig ("", config); 方法的最后会 把ModuleConfig对象放置到servletContext中 (参见 Ⅴ )
protected String prefix = null;
protected HashMap actionConfigs = null;
protected List actionConfigList = null;
protected String actionFormBeanClass = "org.apache.struts.action.ActionFormBean";
protected String actionMappingClass = "org.apache.struts.action.ActionMapping";
protected String actionForwardClass = "org.apache.struts.action.ActionForward";
protected boolean configured = false;
protected ControllerConfig controllerConfig = null;
protected HashMap exceptions = null;
protected HashMap formBeans = null;
protected HashMap forwards = null;
protected HashMap messageResources = null;
protected ArrayList plugIns = null;
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.exceptions = new HashMap();
this.formBeans = new HashMap();
this.forwards = new HashMap();
this.messageResources = new HashMap();
this.plugIns = new ArrayList();
}
Ⅲ
protected String config = "/WEB-INF/struts-config.xml"; // ② initOther(); ⑤ initModuleConfig ();
protected Digester configDigester = null; // ⑤ initModuleConfig ();
// 初始化Digester,
Digester digester = initConfigDigester();
initConfigDigester(); 所做的工作:
// Create a new Digester instance with standard capabilities
configDigester = new Digester();
configDigester.setNamespaceAware(true);
configDigester.setValidating(this.isValidating());
configDigester.setUseContextClassLoader(true);
// 解析struts配置文件之前,首先添加默认的解析规则
configDigester.addRuleSet(new ConfigRuleSet());
for (int i = 0; i < registrations.length; i += 2) {
URL url = this.getClass().getResource(registrations[i + 1]);
if (url != null) {
configDigester.register(registrations[i], url.toString());
}
}
// 通过getServletConfig().getInitParameter("rulesets");从web.xml中读取用户自定义的解析规则(用","分开的org.apache.commons.digester.RuleSet列表)
this.addRuleSets();
.......