深入研究Struts2(二)-StrutsPrepareAndExecuteFilter源码剖析

在面试的时候,很多人经常会被问到:'
摘要由CSDN通过智能技术生成

本文绝对原创,呕心沥血读了2天, 欢迎大家转载, 但是请朋友们尊重一下劳动成果,转载请注明出处

http://blog.csdn.net/izard999/article/details/40143439


在面试的时候,很多人经常会被问到:Struts2与Struts1的区别..我只想说, 最根本的区别是Struts2基于Filter,Struts1基于Servlet, 在Web容器中, Filter的优先级是高于Servlet的

那么上一篇文章中, 我给大家呈现那个官方的大图上面有个FilterDispatcher, 没错.  它就是Struts2的核心过滤器. 但是后来被遗弃

Deprecated. Since Struts 2.1.3, use StrutsPrepareAndExecuteFilter instead or StrutsPrepareFilter and StrutsExecuteFilter if needing using the ActionContextCleanUp filter in addition to this one

为什么遗弃我之前有所提到.  所以下面会研究StrutsPrepareAndExecuteFilter , 而不会再提及FilterDispatcher了.

在web.xml中我们指定Struts2的Filter为:

<filter>
	<filter-name>struts2</filter-name>
	<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
	<filter-name>struts2</filter-name>
	<url-pattern>/*</url-pattern>
</filter-mapping>

从这里看得出来, Struts2官方起名字还是挺有意思的.. ng是什么.?   ng是next generation的缩写, 下一代产品

下面正题开始, StrutsPrepareAndExecuteFilter源码剖析,  有三个属性:

protected PrepareOperations prepare; //准备的一些操作
protected ExecuteOperations execute; //执行的一些操作
protected List<Pattern> excludedPatterns; //排斥的一些匹配路径

StrutsPrepareAndExecuteFilter与普通的Filter并无区别,方法除继承自Filter外,仅有一个回调方法,我们将按照Filter方法调用顺序,由init—>doFilter—>destroy顺序地分析源码。

1、init()

public void init(FilterConfig filterConfig) throws ServletException {
        InitOperations init = new InitOperations();
        Dispatcher dispatcher = null;
        try {
<span style="white-space:pre">	</span>    //封装filterConfig,其中有个主要方法getInitParameterNames将参数名字以String格式存储在List中 
            FilterHostConfig config = new FilterHostConfig(filterConfig);
            // 初始化struts内部日志  
            init.initLogging(config);
	    //创建dispatcher ,并初始化,这部分下面我们重点分析,初始化时加载哪些些资源 
            dispatcher = init.initDispatcher(config);
	    // 初始化静态资源(静态资源后面会有讲解)
            init.initStaticContentLoader(config, dispatcher);

	    //初始化类属性:prepare 、execute   
            prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
            execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
	    //创建排斥路径列表
            this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);
	    //回调空的postInit方法  
            postInit(dispatcher, filterConfig);
        } finally {
            if (dispatcher != null) {
                dispatcher.cleanUpAfterInit();
            }
            init.cleanup();
        }
    }
首先看下FilterHostConfig ,源码如下:

/**
 * Host configuration that wraps FilterConfig
 */
public class FilterHostConfig implements HostConfig {

    private FilterConfig config;

    public FilterHostConfig(FilterConfig config) {
        this.config = config;
    }
    /** 
     *  根据init-param配置的param-name获取param-value的值 
     */   
    public String getInitParameter(String key) {
        return config.getInitParameter(key);
    }

    /** 
     *  返回初始化参数名的List 
     */   
    public Iterator<String> getInitParameterNames() {
        return MakeIterator.convert(config.getInitParameterNames());
    }

    public ServletContext getServletContext() {
        return config.getServletContext();
    }
}
 只有短短的几行代码,getInitParameterNames是这个类的核心,将Filter初始化参数名称有枚举类型转为Iterator。此类的主要作为是对filterConfig 封装。

重点来了,创建并初始化Dispatcher   
 public Dispatcher initDispatcher( HostConfig filterConfig ) {
        Dispatcher dispatcher = createDispatcher(filterConfig);
        dispatcher.init();
        return dispatcher;
    }

创建Dispatcher,会读取 filterConfig 中的配置信息,将配置信息解析出来,封装成为一个Map,然后根据ServletContext和参数Map构造Dispatcher :  
private Dispatcher createDispatcher( HostConfig filterConfig ) {
        Map<String, String> params = new HashMap<String, String>();
        for ( Iterator e = filterConfig.getInitParameterNames(); e.hasNext(); ) {
            String name = (String) e.next();
            String value = filterConfig.getInitParameter(name);
            params.put(name, value);
        }
        return new Dispatcher(filterConfig.getServletContext(), params);
    }
很多人问Struts2配置文件的加载顺序是什么? 不用死记硬背, 源码里面就有.
Dispatcher初始化,加载struts2的相关配置文件,将按照顺序逐一加载:default.properties,struts-default.xml,struts-plugin.xml,struts.xml,……
</pre><pre name="code" class="java">/**
 *初始化过程中依次加载如下配置文件
 */
public void init() {

    	if (configurationManager == null) {
    		configurationManager = new ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);
    	}

        try {
            //加载org/apache/struts2/default.properties
            init_DefaultProperties(); // [1]
            //加载struts-default.xml,struts-plugin.xml,struts.xml
            init_TraditionalXmlConfigurations(); // [2]
            init_LegacyStrutsProperties(); // [3]
            //用户自己实现的ConfigurationProviders类            
            init_CustomConfigurationProviders(); // [5]
            //Filter的初始化参数
            init_FilterInitParameters() ; // [6]
            init_AliasStandardObjects() ; // [7]

            Container container = init_PreloadConfiguration();
            container.inject(this);
            init_CheckConfigurationReloading(container);
            init_CheckWebLogicWorkaround(container);

            if (!dispatcherList
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值