Struts 源码学习之ActionServlet ( 二)

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 替换了原来传统的在 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();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值