④ 調用 initChain(); 讀取web.xml中命令鏈文件初始值chainConfigjava
protected String chainConfig = "org/apache/struts/chain/chain-config.xml";web
// ④ initChain();apache
// 如沒有chainConfig參數,則使用默認 "org/apache/struts/chain/chain-config.xml"app
String value;webapp
value = getServletConfig().getInitParameter("chainConfig");this
if (value != null) {url
chainConfig = value;spa
}插件
ConfigParser parser = new ConfigParser();debug
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();
.......
Ⅳ
/* 循環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的初始化工做。