struts1源码学习2(initChain)

先上代码

protected void initChain()
        throws ServletException {
        // Parse the configuration file specified by path or resource
        try {
        //还是先从servlet配置中找chainConfig
        //默认值是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;
            for (Iterator i = urls.iterator(); i.hasNext();) {
                resource = (URL) i.next();
                log.info("Loading chain catalog from " + resource);
                parser.parse(resource);
            }
        } catch (Exception e) {
            log.error("Exception loading resources", e);
            throw new ServletException(e);
        }
    }

这段代码比较少,也比较简单,就是解析chain-config.xml文件。(如果是多个文件,中间逗号分隔)

但是这个文件对struts的意义暂时还不是很清楚。(看字面的话,貌似是命令链条,用的装饰器模式?)

chain-config.xml文件

<?xml version="1.0" ?>
<catalog name="struts">
    <define name="lookup"
            className="org.apache.commons.chain.generic.LookupCommand"/>
    <!-- ========== Servlet Complete Request Chain ========================= -->
    <chain name="servlet-standard">
        <!-- Establish exception handling filter -->
        <command
                className="org.apache.struts.chain.commands.ExceptionCatcher"
                catalogName="struts"
                exceptionCommand="servlet-exception"/>
        <lookup
                catalogName="struts"
                name="process-action"
                optional="false"/>
        <lookup
                catalogName="struts"
                name="process-view"
                optional="false"/>
    </chain>
    <!-- ========== Action Processing chain ======================== -->
    <chain name="process-action">
        <!-- Look up optional preprocess command -->
        <lookup
                catalogName="struts"
                name="servlet-standard-preprocess"
                optional="true"/>
        <command
                className="org.apache.struts.chain.commands.servlet.SelectLocale"/>
        <command
                className="org.apache.struts.chain.commands.servlet.SetOriginalURI"/>
        <command
                className="org.apache.struts.chain.commands.servlet.RequestNoCache"/>
        <command
                className="org.apache.struts.chain.commands.servlet.SetContentType"/>
        <command
                className="org.apache.struts.chain.commands.RemoveCachedMessages"/>
        <command
                className="org.apache.struts.chain.commands.servlet.SelectAction"/>
        <command
                className="org.apache.struts.chain.commands.servlet.AuthorizeAction"/>
        <command
                className="org.apache.struts.chain.commands.CreateActionForm"/>
        <command
                className="org.apache.struts.chain.commands.servlet.PopulateActionForm"/>
        <command
                className="org.apache.struts.chain.commands.servlet.ValidateActionForm"/>
        <command
                className="org.apache.struts.chain.commands.servlet.SelectInput"/>
        <command
                className="org.apache.struts.chain.commands.ExecuteCommand"/>
        <command
                className="org.apache.struts.chain.commands.servlet.SelectForward"/>
        <command
                className="org.apache.struts.chain.commands.SelectInclude"/>
        <command
                className="org.apache.struts.chain.commands.servlet.PerformInclude"/>
        <command
                className="org.apache.struts.chain.commands.servlet.CreateAction"/>
        <command
                className="org.apache.struts.chain.commands.servlet.ExecuteAction"/>
    </chain>
    <!-- ========== View Processing chain ======================== -->
    <chain name="process-view">
        <command
                className="org.apache.struts.chain.commands.ExecuteForwardCommand"/>
        <command
                className="org.apache.struts.chain.commands.servlet.PerformForward"/>
    </chain>
    <chain name="servlet-exception">
        <command
                className="org.apache.struts.chain.commands.servlet.ExceptionHandler"/>
        <command
                className="org.apache.struts.chain.commands.servlet.PerformForward"/>
    </chain>
</catalog>

目测还是要从

ConfigParser

这个类入手

public class ConfigParser {
    private Digester digester = null;
    private RuleSet ruleSet = null;
    private boolean useContextClassLoader = true;
    public Digester getDigester() {
        if (digester == null) {
            digester = new Digester();
            RuleSet ruleSet = getRuleSet();
            digester.setNamespaceAware(ruleSet.getNamespaceURI() != null);
            digester.setUseContextClassLoader(getUseContextClassLoader());
            digester.setValidating(false);
            digester.addRuleSet(ruleSet);
        }
        return (digester);
    }
    public RuleSet getRuleSet() {
        if (ruleSet == null) {
            ruleSet = new ConfigRuleSet();
        }
        return (ruleSet);
    }
    public void setRuleSet(RuleSet ruleSet) {
        this.digester = null;
        this.ruleSet = ruleSet;
    }
    public boolean getUseContextClassLoader() {
        return (this.useContextClassLoader);
    }
    public void setUseContextClassLoader(boolean useContextClassLoader) {

        this.useContextClassLoader = useContextClassLoader;

    }
    public void parse(Catalog catalog, URL url) throws Exception {
        Digester digester = getDigester();
        digester.clear();
        digester.push(catalog);
        digester.parse(url);
    }
    public void parse(URL url) throws Exception {
        Digester digester = getDigester();
        digester.clear();
        digester.parse(url);
    }
}

直接找到parse方法,好吧,三行,再看getDigester方法,好,里面出现了RuleSet,目测解析就在这个

ConfigRuleSet里面。

ConfigRuleSet代码(各种setget被我去掉了)

public class ConfigRuleSet extends RuleSetBase {
//貌似是分类、链条类?className也出现了,估计就是这里
    private String catalogClass = "org.apache.commons.chain.impl.CatalogBase";
    private String catalogElement = "catalog";
    private String chainClass = "org.apache.commons.chain.impl.ChainBase";
    private String chainElement = "chain";
    private String classAttribute = "className";
    private String commandElement = "command";
    private String defineElement = "define";
    private String nameAttribute = "name";
    public void addRuleInstances(Digester digester) {
        // catalog用ConfigCatalogRule处理,并且将成功处理的catalog放入CatalogFactory的一个map中,此map的key是catalog的classloader
        digester.addRule("*/" + getCatalogElement(),
                         new ConfigCatalogRule(nameAttribute, catalogClass));
        digester.addSetProperties("*/" + getCatalogElement());
        //以下都是解析catalog的代码
        // 创建org.apache.commons.chain.impl.ChainBase这个类
        //解析chain,三个参数,第一个是匹配表达式,第二个是默认创建类名称,第三个是当匹配表达式所在的属性来作为类名
        digester.addObjectCreate("*/" + getChainElement(),
                                 getChainClass(),
                                 getClassAttribute());
        digester.addSetProperties("*/" + getChainElement());
        //规则ConfigRegisterRule
        digester.addRule("*/" + getChainElement(),
                         new ConfigRegisterRule(nameAttribute));

        // Add rules for a command element
        digester.addObjectCreate("*/" + getCommandElement(),
                                 null,
                                 getClassAttribute());
        digester.addSetProperties("*/" + getCommandElement());
        digester.addRule("*/" + getCommandElement(),
                         new ConfigRegisterRule(nameAttribute));

        // Add rules for a define element
        digester.addRule("*/" + getDefineElement(),
                         new ConfigDefineRule(getNameAttribute(),
                                              getClassAttribute()));

    }


}

CatalogFactory将解析后的catalog放入自身map,留作后续使用


你可能感兴趣的:(java,xml,Digester,initChain)