版權所有:(xiaodaoxiaodao)藍小刀 ?? xiaodaoxiaodao@gmail.com

http://www.tkk7.com/xiaodaoxiaodao/archive/2007/04/26/113744.html ???? ??

轉載請注明來源/作者

?

Struts 源碼學習之ActionServlet ( )

?

④ 調用 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 替換了原來傳統(tǒng)的在 RequestProcessor 類中執(zhí)行的 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); 創(chuàng)建 ModuleConfig 對象。Struts中的MessageResource、PlugIn、數據源等,都是通過ModuleConfig來實現(xiàn)的。

// 初始化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配置文件之前,首先添加默認的解析規(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());

??? }

}

// 通過getServletConfig().getInitParameter("rulesets");web.xml中讀取用戶自定義的解析規(guī)則(用","分開的org.apache.commons.digester.RuleSet列表)

this.addRuleSets();

.......

?

/* 循環(huán)struts配置文件(用","分開的多個struts配置文件)并解析, parseModuleConfigFile 執(zhí)行之后可以 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);

在上面第步的中我們已經創(chuàng)建了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);

在上面第步的中我們已經創(chuàng)建了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、forwardsmessageResources、plugIns等的配置等變得不可改變 */

moduleConfig.freeze();

?

?

⑩ 解析以"config/"開頭的其他struts配置文件

// 遍歷web.xmlservletConfig配置的 initParameterNames

// 如發(fā)現(xiàn)以" 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配置文件之后ActionServletinit()方法還需要做

// 初始化其他模塊的前綴

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 的核心類ActionServletinit()方法完成servlet的初始化工作。

?

?

?

版權所有:(xiaodaoxiaodao)藍小刀 ?? xiaodaoxiaodao@gmail.com

?