struts2源碼分析(一)(初始化)

struts2容器的初始化

1、通過web.xml配置文件的Filter配置進入到StrutsPrepareAndExecute(org.apache.struts2.dispatcher.ng.filter包)

該類是一個Filter類,其實現了兩個接口。分別爲StrutsStatics和Filter,其中StrutsStatics(org.apache.struts2)這個文件中保存了struts2用到的常量,這些常量有HTTP_REQUEST(http_request),HTTP_RESPONSE(http_response),SERVLET_DISPATCHER(servlet_dispatcher),SERVLET_CONTEXT(servlet_context),PAGE_CONTEXT(page_context),STRUTS_PORTLET_CONTEXT(struts_portlet_context),STRUTS_ACTION_TAG_INVOCATION(struts_tag_invocation).Filter接口就不做說明。

接下來分析該類內部的init(FilterConfig filterConfig)方法,該方法的代碼如下:

public void init(FilterConfig filterConfig) throws ServletException {
    	//創建一個初始化所有操作的init實例
        InitOperations init = new InitOperations();//1
        try {
        	//對filterConfig中的信息進行整理
            FilterHostConfig config = new FilterHostConfig(filterConfig);//2
            //配置日子管理類
            init.initLogging(config);//3
            //初始化Dispatcher,這行代碼是核心內容
            Dispatcher dispatcher = init.initDispatcher(config);//4
            init.initStaticContentLoader(config, dispatcher);//5
            //實例化prepare
            prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);//6
            //實例化execute
            execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);//7
	   this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);//8

            postInit(dispatcher, filterConfig);//9
        } finally {
            init.cleanup();//10
        }

    }

具體分析如下:

①InitOperations init = new InitOperations();//1

InitOperations(org.apache.struts2.dispatcher.ng)該類負責初始化操作;

 這行代碼主要創建了一個InitOperations實例,其構造方法如下:

    /**
     * 默認無參數構造方法
      */
    public InitOperations() {
    }

②FilterHostConfig config = new FilterHostConfig(filterConfig);//2

FilterHostConfig(org.apache.struts2.dispatcher.ng.filter)對filterConfig中的信息進行整理該類的主要方法如下

public class FilterHostConfig implements HostConfig {

    //常量,用於接收FilterConfig
    private FilterConfig config;

    /**
     * 構造方法,在這個構造方法中初始化FilterConfig常量
     * @param config FilterConfig的實體對象
     */
    public FilterHostConfig(FilterConfig config) {
        this.config = config;
    }
    
    /**
     * 通過KEY得到在web.xml中配置的參數
     */
    public String getInitParameter(String key) {
        return config.getInitParameter(key);
    }

    /**
     * 以Iterator的形式返回配置中的所有配置名稱
     */
    public Iterator getInitParameterNames() {
        return MakeIterator.convert(config.getInitParameterNames());
    }

    /**
     * 得到Servlet容器
     */
    public ServletContext getServletContext() {
        return config.getServletContext();
    }
}

 

繼承的接口HostConfig(org.apache.struts2.dispatcher.ng)

public interface HostConfig {

    /**
     * @param key The parameter key
     * @return The parameter value
     */
    String getInitParameter(String key);

    /**
     * @return A list of parameter names
     */
    Iterator<String> getInitParameterNames();

    /**
     * @return The servlet context
     */
    ServletContext getServletContext();
}


③init.initLogging(config);

InitOperations(org.apache.struts2.dispatcher.ng)類中的initLogging(config)方法
 該方法的主要目的是初始化配置文件中配置的loggerFactory

    /**
     * 初始化struts2內部的日子信息
      */
    public void initLogging( HostConfig filterConfig ) {
    	//從web.xml中的Filter中獲取loggerFactory的參數
    	String factoryName = filterConfig.getInitParameter("loggerFactory");
    	/**
    	 * 平時,不在web的filter中配置該選項(loggerFactory),所以不需要分析該部分代碼;
    	 * 如果用戶需要配置的話,配置的類要實現LoggerFactory這個抽象類
    	 */
        if (factoryName != null) {
            try {
            	//如果在配置文件中配置了該選項,則採用java中的反射機制,加載到LoggerFactory中
                Class cls = ClassLoaderUtil.loadClass(factoryName, this.getClass());
                LoggerFactory fac = (LoggerFactory) cls.newInstance();
                LoggerFactory.setLoggerFactory(fac);
            } catch ( InstantiationException e ) {
                System.err.println("Unable to instantiate logger factory: " + factoryName + ", using default");
                e.printStackTrace();
            } catch ( IllegalAccessException e ) {
                System.err.println("Unable to access logger factory: " + factoryName + ", using default");
                e.printStackTrace();
            } catch ( ClassNotFoundException e ) {
                System.err.println("Unable to locate logger factory class: " + factoryName + ", using default");
                e.printStackTrace();
            }
        }
    }

④Dispatcher dispatcher = init.initDispatcher(config);

InitOperations(org.apache.struts2.dispatcher.ng)類中的initDispatcher(filterConfig)方法
 該方法的主要目的是初始化Dispatcher(該模塊是核心內容,將在第二部分進行說明)

    /**
     * 創建和初始化dispatcher
     */
    public Dispatcher initDispatcher( HostConfig filterConfig ) {
       //創建一個dispatcher,並把filterConfig作爲參數傳遞進去
        Dispatcher dispatcher = createDispatcher(filterConfig);//1:
       //dispatcher的初始化操作,很重要的部分
        dispatcher.init();//2:
       return dispatcher;
    }

⑤init.initStaticContentLoader(config, dispatcher);

InitOperationos(org.apache.struts2.dispatcher.ng)類中的initStaticContentLoader(filterConfig, Dispatcher)該方法的主要目的是
 初始化靜態內容裝載器和攔截器配置,具體代碼如下(該部分的詳細介紹將在第二部分進行說明)

⑥prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
 初始化一個PrepareOperations(org.apache.struts2.dispatcher.ng)(該段代碼的具體作用將在第五部分進行介紹)
 ⑦execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
 初始化一個ExecuteOperations(org.apache.struts2.dispatcher.ng)(該段代碼的具體作用將在第五部分進行介紹)
 ⑧this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);
 調用init的方法,提取一個請求過濾列表(該段代碼的具體作用將在第五部分進行介紹)
 ⑨postInit(dispatcher, filterConfig);
 該方法屬於StrutsPrepareAndExecuteFilter(org.apache.struts2.dispatcher.ng.filer)中的方法(具體作用將在第五部分進行介紹)
 ⑩init.cleanup();
 清空ActionContext(具體作用將在第五部分進行介紹)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章