Struts 源碼學習之ActionServlet ( 二)

④ 調用 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中的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;

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 formBeansforwardsmessageResourcesplugIns等的配置,並把獲得的全部值封裝到對象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 formBeansforwardsmessageResourcesplugIns等的配置等變得不可改變 */

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的初始化工做。

相關文章
相關標籤/搜索