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,留作后续使用

struts1源码学习2(initChain)

时间: 2024-08-29 20:21:24

struts1源码学习2(initChain)的相关文章

struts1源码学习3

  public void init() throws ServletException {         final String configPrefix = "config/";         final int configPrefixLength = configPrefix.length() - 1;         // Wraps the entire initialization in a try/catch to better handle         //

struts1源码学习1

初始化方法学习 public class ActionServlet extends HttpServlet //servlet初始化  public void init() throws ServletException {         final String configPrefix = "config/";         final int configPrefixLength = configPrefix.length() - 1;         // Wraps t

FireMonkey 源码学习(5)

(5)UpdateCharRec 该函数的源码分析如下: procedure TTextLayoutNG.UpdateCharRec(const ACanvas: TCanvas; NeedBitmap: Boolean; var NewRec: PCharRec; HasItem: Boolean; const CharDic: TCharDic; const AFont: TFont; const Ch: UCS4Char; const NeedPath: Boolean = False);

jquery源码学习

jQuery 源码学习是对js的能力提升很有帮助的一个方法,废话不说,我们来开始学习啦 我们学习的源码是jquery-2.0.3已经不支持IE6,7,8了,因为可以少学很多hack和兼容的方法. jquery-2.0.3的代码结构如下 首先最外层为一个闭包, 代码执行的最后一句为window.$ = window.jquery = jquery 让闭包中的变量暴露倒全局中. 传参传入window是为了便于压缩 传入undefined是为了undifined被修改,他是window的属性,可以被修

Hadoop源码学习笔记(1) ——第二季开始——找到Main函数及读一读Configure类

Hadoop源码学习笔记(1) ——找到Main函数及读一读Configure类 前面在第一季中,我们简单地研究了下Hadoop是什么,怎么用.在这开源的大牛作品的诱惑下,接下来我们要研究一下它是如何实现的. 提前申明,本人是一直搞.net的,对java略为生疏,所以在学习该作品时,会时不时插入对java的学习,到时也会摆一些上来,包括一下设计模式之类的.欢迎高手指正. 整个学习过程,我们主要通过eclipse来学习,之前已经讲过如何在eclipse中搭建调试环境,这里就不多述了. 在之前源码初

HSQLDB源码学习——数据库安装启动及JDBC连接

HSQLDB 是一个轻量级的纯Java开发的开放源代码的关系数据库系统.因为HSQLDB的轻量(占用空间小),使用简单,支持内存运行方式等特点,HSQLDB被广泛用于开发环境和某些中小型系统中. 在http://sourceforge.net/projects/hsqldb/files/下载了HSQLDB 1.8.0版本.把下载的zip文件解压缩至任意目录例如c:\hsqldb1.8便完成安装. hsqldb有四种运行模式: 一.内存(Memory-Only)模式:所有数据都在内存里操作.应用程

lodash源码学习(10)

_.delay(func, wait, [args]) 延迟wait毫秒之后调用该函数,添加的参数为函数调用时的参数 //delay.js var baseDelay = require('./_baseDelay'),//baseDelay方法 baseRest = require('./_baseRest'),//创建使用rest参数方法 toNumber = require('./toNumber');//转化为数字 /** * * @param {Function} func 需要延迟执

lodash源码学习(2)

继续学习lodash,依然是数组的方法 “Array” Methods _.indexOf(array, value, [fromIndex=0]) 获取value在数组 array所在的索引值 使用 SameValueZero方式比较(第一个全等===的元素). 如果 fromIndex 值是负数, 则从array末尾起算 该方法依赖于strictIndexOf和baseIndexOf方法,先看它们的源码 //_strictIndexOf.js /** * _.indexOf的专业版本,对元素

jQuery源码学习感想

还记得去年(2015)九月份的时候,作为一个大四的学生去参加美团霸面,结果被美团技术总监教育了一番,那次问了我很多jQuery源码的知识点,以前虽然喜欢研究框架,但水平还不足够来研究jQuery源码,那时我不明白他们为何要求那么高,现在才知道,原来没那么高,他问的都是jQuery最基本的框架架构,不过对于不知道的来说,再简单我也是不知道,那时写了一篇博文去吐槽了一下,那时候也是我自己真正激发自己的时候,那时候我说我一定要搞好自己的jQuery基础,没想到那么快就实现了,一个月的源码学习时间就结束