版權(quán)所有:(xiaodaoxiaodao)藍(lán)小刀
??
xiaodaoxiaodao@gmail.com
http://www.aygfsteel.com/xiaodaoxiaodao/archive/2007/04/26/113744.html
????
??
轉(zhuǎn)載請(qǐng)注明來(lái)源/作者
Struts
源碼學(xué)習(xí)之ActionServlet
(
二)
④ 調(diào)用
initChain();
讀取web.xml中命令鏈文件初始值chainConfig
protected String chainConfig = "org/apache/struts/chain/chain-config.xml";
//
④
initChain();
//
如沒(méi)有chainConfig參數(shù),則使用默認(rèn)
"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
替換了原來(lái)傳統(tǒng)的在
RequestProcessor
類中執(zhí)行的
HTTP
請(qǐng)求處理
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"/>
.......
好處是充分降低了代碼內(nèi)部方法與方法之間的耦合度
************************************************************/
在④/⑤之間
//
把servlet對(duì)象存儲(chǔ)到servletContext中,屬性名為Globals.ACTION_SERVLET_KEY
(
"
org.apache.struts.action.ACTION_SERVLET
"
)
getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);
⑤ 調(diào)用
initModuleConfigFactory();
和
initModuleConfig("", config);
創(chuàng)建
ModuleConfig
對(duì)象。Struts中的MessageResource、PlugIn、數(shù)據(jù)源等,都是通過(guò)ModuleConfig來(lái)實(shí)現(xiàn)的。
//
初始化ModuleConfig配置工廠
initModuleConfigFactory();
//
⑴
//
由配置工廠實(shí)例化一個(gè)ModuleConfig的對(duì)象
ModuleConfig moduleConfig = initModuleConfig("", config); //
⑵
⑴
initModuleConfigFactory();
所做的工作:
//
得到web.xml中"configFactory"參數(shù),如果找不到,則使用
默認(rèn)工廠
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"參數(shù)-->
????? <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通過(guò)classLoader加載一個(gè)
org.apache.struts.config.impl.DefaultModuleConfigFactory
Ⅱ
ModuleConfig config = factoryObject.createModuleConfig(prefix);
方法中:
//
通過(guò)new ModuleConfigImpl(prefix);設(shè)置一些變量的初始值,在
initModuleConfig
("", config);
方法的最后會(huì)
把ModuleConfig對(duì)象放置到servletContext中 (參見(jiàn)
Ⅴ
)
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配置文件之前,首先添加默認(rèn)的解析規(guī)則
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());
??? }
}
//
通過(guò)getServletConfig().getInitParameter("rulesets");從web.xml中讀取用戶自定義的解析規(guī)則(用","分開的org.apache.commons.digester.RuleSet列表)
this.addRuleSets();
.......
Ⅳ
/*
循環(huán)struts配置文件(用","分開的多個(gè)struts配置文件)并解析,
parseModuleConfigFile
執(zhí)行之后可以
從struts-config.xml等配置文件中得到
Ⅱ
中
actionConfigs/actionConfigList
、exceptions 、formBeans、forwards、messageResources、plugIns等的配置,并把得到的所有值封裝到對(duì)象ModuleConfig對(duì)象(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存儲(chǔ)到servletContext中
,屬性名為Globals.MODULE_KEY
(
"
org.apache.struts.action.MODULE
"
)
getServletContext().setAttribute(Globals.MODULE_KEY
??????????? + config.getPrefix(), config);
⑥ 用戶資源文件的初始化
initModuleMessageResources(moduleConfig);
在上面第⑤步的Ⅱ中我們已經(jīng)創(chuàng)建了ModuleConfig對(duì)象并在Ⅲ和Ⅵ中從struts-config.xml等配置文件中得到得到一些配置且封裝到ModuleConfig對(duì)象中,所以在下面可以直接使用initModuleMessageResources(moduleConfig);
initModuleMessageResources(moduleConfig);
所做的工作:
⑴
/*
從moduleConfig中讀取所有的資源文件(包括
① 內(nèi)部資源文件
和
⑤
中Ⅵ利用Digester讀取的struts配置文件指定的用戶資源文件) */
MessageResourcesConfig[] mrcs = config.findMessageResourcesConfigs();
注:
此時(shí)moduleConfig中默認(rèn)只含有① 內(nèi)部資源文件ActionResources.properties
⑵
//
把resources(包括
① 內(nèi)部資源文件
和
⑥ 用戶資源文件
)存儲(chǔ)到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);
在上面第⑤步的Ⅱ中我們已經(jīng)創(chuàng)建了ModuleConfig對(duì)象并在Ⅲ和Ⅵ中從struts-config.xml等配置文件中得到得到一些配置且封裝到ModuleConfig對(duì)象中,所以在下面可以直接使用initModulePlugIns(ModuleConfig config);
initModulePlugIns(moduleConfig);
所做的工作:
⑴
//
從moduleConfig中讀取所有的插件文件
PlugInConfig[] plugInConfigs = config.findPlugInConfigs();
PlugIn[] plugIns = new PlugIn[plugInConfigs.length];
⑵
//
把所有plugIns存儲(chǔ)到servletContext中
//
屬性名為Globals.PLUG_INS_KEY + config.getPrefix()
.......
getServletContext().setAttribute(Globals.PLUG_INS_KEY
??????????? + config.getPrefix(), plugIns);
.......
⑧ 把struts配置文件中的其他配置
存儲(chǔ)到servletContext中
,包括
initModuleFormBeans(moduleConfig);
initModuleForwards(moduleConfig);
initModuleExceptionConfigs(moduleConfig);
initModuleActions(moduleConfig);
⑨ 調(diào)用
moduleConfig.freeze();
固定組件配置
/*
使ModuleConfig中的
actionConfigs/actionConfigList
、exceptions 、formBeans、forwards、messageResources、plugIns等的配置等變得不可改變 */
moduleConfig.freeze();
⑩ 解析以"config/"開頭的其他struts配置文件
//
遍歷web.xml中servletConfig配置的
initParameterNames
//
如發(fā)現(xiàn)以"
config/
"
開始的parameter,則根據(jù)此值初始化其它的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"參數(shù)-->
??????????? <param-value>/WEB-INF/struts-config.xml</param-value>
??????? </init-param>
??????? <init-param>
??????????? <param-name>config/admin</param-name> <!--
得到"config/admin"參數(shù)-->
??????????? <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存儲(chǔ)到servletContext中,屬性名為
Globals.MODULE_PREFIXES_KEY
(
"
org.apache.struts.globals.MODULE_PREFIXES
"
)
*/
context.setAttribute(Globals.MODULE_PREFIXES_KEY, prefixes);
⑵
//
設(shè)置configDigester = null,釋放內(nèi)存
this.destroyConfigDigester();
至此struts 的核心類ActionServlet的init()方法完成servlet的初始化工作。
版權(quán)所有:(xiaodaoxiaodao)藍(lán)小刀
??
xiaodaoxiaodao@gmail.com