Struts 源码学习之ActionServlet ( 二)

来源:互联网 发布:mysql qps 和 tps 编辑:程序博客网 时间:2024/05/17 07:42

④ 调用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中的MessageResourcePlugIn、数据源等,都是通过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;

protectedstatic 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;

protectedstatic 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/actionConfigListexceptionsformBeansforwardsmessageResourcesplugIns等的配置,并把得到的所有值封装到对象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/actionConfigListexceptionsformBeansforwardsmessageResourcesplugIns等的配置等变得不可改变 */

moduleConfig.freeze();

 

 

⑩ 解析以"config/"开头的其他struts配置文件

//遍历web.xmlservletConfig配置的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配置文件之后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的初始化工作。

原创粉丝点击