国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Struts的資源文件時如何初始化的--struts源碼學(xué)習(xí) - 輪上飛 - BlogJa...

作者:zhyiwww        zhyiwww@163.com                          |

分以下幾步來理解:

[1] Web 應(yīng)用如何知道使用的是 Struts

我們知道,在 Web 工程的 /WEB-INF/ 目錄下面,我們有兩個配置文件

Web.xml Struts-config.xml.

一般情況下就只有一個 web.xml 文件,如果系統(tǒng)是用了 struts 技術(shù)的話,那么就會有 struts-config.xml 文件。

[2] 系統(tǒng)是如何啟動和初始化 struts

Web.xml 中有這么一段代碼:

  < servlet >

    < servlet-name > action </ servlet-name >

    < servlet-class > org.apache.struts.action.ActionServlet </ servlet-class >

    < init-param >

      < param-name > config </ param-name >

      < param-value > /WEB-INF/struts-config.xml </ param-value >

    </ init-param >

    < init-param >

      < param-name > debug </ param-name >

      < param-value > 3 </ param-value >

    </ init-param >

    < init-param >

      < param-name > detail </ param-name >

      < param-value > 3 </ param-value >

    </ init-param >

    < load-on-startup > 0 </ load-on-startup >

  </ servlet >

  < servlet >

    < servlet-name > startThread </ servlet-name >

    < servlet-class > com.cgogo.ypindex.StartThread </ servlet-class >

    < init-param >

    < param-name > startParam </ param-name >

    < param-value > 2 </ param-value >

    </ init-param >

    < load-on-startup > 1 </ load-on-startup >

  </ servlet >  

  < servlet-mapping >

    < servlet-name > action </ servlet-name >

    < url-pattern > *.do </ url-pattern >

  </ servlet-mapping >

web.xml 中會配置 struts 的中央控制器類。 Web.xml 配置文件的初始化是由容器來實現(xiàn)載入和初始化的。如果你使用的是 tomcat 的話,那么就是由 tomcat 在啟動的時候會載入此 web.xml 文件,也就為此 web 應(yīng)用創(chuàng)建了一個 web Context, context 也就是你 Web 應(yīng)用的訪問入口。

載入中央控制器 org.apache.struts.action.ActionServlet ,這是一個 Servlet, 那么,其就要進行 servlet 的初始化操作。此 action 是如何對 Struts 系統(tǒng)進行初始化的呢?

[3] init()-- ActionServlet 如何初始化 Struts 系統(tǒng)?

看一下 ActionServlet 的源代碼:

我們知道,在一個 Servlet 中,在其啟動的時候,首先要執(zhí)行 init() 方法,那么我們先來看一下 actionServlet init() 方法的源代碼:

    /**

     * <p>Initialize this servlet.  Most of the processing has been factored into

     * support methods so that you can override particular functionality at a

     * fairly granular level.</p>

     *

     * @exception ServletException if we cannot configure ourselves correctly

     */

    public void init() throws ServletException {

 

        // Wraps the entire initialization in a try/catch to better handle

        // unexpected exceptions and errors to provide better feedback

        // to the developer

        try {

(1)      initInternal();

(2)      initOther();

(3)      initServlet();

   

            getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this);

(4)      initModuleConfigFactory();

            // Initialize modules as needed

            ModuleConfig moduleConfig = initModuleConfig("", config);

(5)      initModuleMessageResources(moduleConfig);

(6)      initModuleDataSources(moduleConfig);

(7)      initModulePlugIns(moduleConfig);

            moduleConfig.freeze();

(8)      初始化配置參數(shù)

            Enumeration names = getServletConfig().getInitParameterNames();

            while (names.hasMoreElements()) {

                String name = (String) names.nextElement();

                if (!name.startsWith("config/")) {

                    continue;

                }

                String prefix = name.substring(6);

                moduleConfig = initModuleConfig

                    (prefix, getServletConfig().getInitParameter(name));

                initModuleMessageResources(moduleConfig);

                initModuleDataSources(moduleConfig);

                initModulePlugIns(moduleConfig);

                moduleConfig.freeze();

            }

   

            this.initModulePrefixes(this.getServletContext());

   

            this.destroyConfigDigester();

        } catch (UnavailableException ex) {

            throw ex;

        } catch (Throwable t) {

 

            // The follow error message is not retrieved from internal message

            // resources as they may not have been able to have been

            // initialized

            log.error("Unable to initialize Struts ActionServlet due to an "

                + "unexpected exception or error thrown, so marking the "

                + "servlet as unavailable.  Most likely, this is due to an "

                + "incorrect or missing library dependency.", t);

            throw new UnavailableException(t.getMessage());

        }   

}

 

先來看一下初始化( 1 )的部分 initInternal() 。

 

[4]   initInternal()-- 內(nèi)部資源文件的初始化

initInternal() 就是實現(xiàn)內(nèi)部資源文件的初始化的,也就是轉(zhuǎn)為 Struts 系統(tǒng)本身提供的以下錯誤信息提示等文字的國際化實現(xiàn)的。我們看一下源代碼是如何實現(xiàn)的:

    /**

     * <p> Initialize our internal MessageResources bundle. </p>

     *

     * @exception ServletException if we cannot initialize these resources

     */

    protected void initInternal() throws ServletException {

 

        // : FIXME : Document UnavailableException

 

        try {

            internal = MessageResources.getMessageResources( internalName );

        } catch (MissingResourceException e) {

            log.error( "Cannot load internal resources from ‘" + internalName + "‘" ,

                e);

            throw new UnavailableException

                ( "Cannot load internal resources from ‘" + internalName + "‘" );

        }

 

}

Struts 根據(jù)配置文件的名字得到一個資源文件。

internalName 就是內(nèi)部資源文件的名稱,其在 actionServlet 中定義:

    /**

     * <p> The Java base name of our internal resources. </p>

     * @since Struts 1.1

     */

    protected String internalName = "org.apache.struts.action.ActionResources" ;

取得后的對象是一個 MessageResources 的對象,保存在 internal 中,

    /**

     * <p>The resources object for our internal resources.</p>

     */

    protected MessageResources internal = null;

經(jīng)過此初始化后, internal 就不在是 null 了。

至此就實現(xiàn)完成了內(nèi)部資源文件的初始化。如果出現(xiàn)了異常的話,那么系統(tǒng)就捕捉到。

 

然后,系統(tǒng)就開始初始化其它的配置,即( 2 initOther();

 

[5] initOther()-- 如何初始化其他的配置的?

    /**

     * <p>Initialize other global characteristics of the controller servlet.</p>

     *

     * @exception ServletException if we cannot initialize these resources

     */

    protected void initOther() throws ServletException {

 

        String value = null;

        value = getServletConfig().getInitParameter("config");

        if (value != null) {

            config = value;

        }

 

        // Backwards compatibility for form beans of Java wrapper classes

        // Set to true for strict Struts 1.0 compatibility

        value = getServletConfig().getInitParameter("convertNull");

        if ("true".equalsIgnoreCase(value)

            || "yes".equalsIgnoreCase(value)

            || "on".equalsIgnoreCase(value)

            || "y".equalsIgnoreCase(value)

            || "1".equalsIgnoreCase(value)) {

 

            convertNull = true;

        }

 

        if (convertNull) {

            ConvertUtils.deregister();

            ConvertUtils.register(new BigDecimalConverter(null), BigDecimal.class);

            ConvertUtils.register(new BigIntegerConverter(null), BigInteger.class);

            ConvertUtils.register(new BooleanConverter(null), Boolean.class);

            ConvertUtils.register(new ByteConverter(null), Byte.class);

            ConvertUtils.register(new CharacterConverter(null), Character.class);

            ConvertUtils.register(new DoubleConverter(null), Double.class);

            ConvertUtils.register(new FloatConverter(null), Float.class);

            ConvertUtils.register(new IntegerConverter(null), Integer.class);

            ConvertUtils.register(new LongConverter(null), Long.class);

            ConvertUtils.register(new ShortConverter(null), Short.class);

        }

 

}

然后就執(zhí)行( 3 initServlet();

 

[6]   initServlet()-- 如何初始化 servlet

這個初始化主要是初始化 servlet 的,哪些 servlet 呢?就是我們在 web.xml 中配置的那些需要在 web application 初始化時就栽入系統(tǒng)的 servlet

這是一個復(fù)雜的過程:

 

我的理解:

       這部分代碼就執(zhí)行一次,僅在初始化的時候執(zhí)行一次。

           /**

     * <p>Initialize the servlet mapping under which our controller servlet

     * is being accessed.  This will be used in the <code>&html:form></code>

     * tag to generate correct destination URLs for form submissions.</p>

     *

     * @throws ServletException if error happens while scanning web.xml

     */

    protected void initServlet() throws ServletException {

 

        // Remember our servlet name

       // 這里保存當(dāng)前的servlet名字,保存在actionServletservletName屬性中

        this.servletName = getServletConfig().getServletName();

 

        // Prepare a Digester to scan the web application deployment descriptor

             

        Digester digester = new Digester();

        digester.push(this);

        digester.setNamespaceAware(true);

        digester.setValidating(false);

 

        // Register our local copy of the DTDs that we can find

        for (int i = 0; i < registrations.length; i += 2) {

            URL url = this.getClass().getResource(registrations[i+1]);

            if (url != null) {

                digester.register(registrations[i], url.toString());

            }

        }

 

        // Configure the processing rules that we need

        digester.addCallMethod("web-app/servlet-mapping",

                               "addServletMapping", 2);

        digester.addCallParam("web-app/servlet-mapping/servlet-name", 0);

        digester.addCallParam("web-app/servlet-mapping/url-pattern", 1);

 

        // Process the web application deployment descriptor

        if (log.isDebugEnabled()) {

            log.debug("Scanning web.xml for controller servlet mapping");

        }

 

    // 取得當(dāng)前的配置文件   

InputStream input =

            getServletContext().getResourceAsStream("/WEB-INF/web.xml");

 

        if (input == null) {

            log.error(internal.getMessage("configWebXml"));

            throw new ServletException(internal.getMessage("configWebXml"));

        }

 

        try {

            // 解析當(dāng)前配置文件

digester.parse(input);

 

        } catch (IOException e) {

            log.error(internal.getMessage("configWebXml"), e);

            throw new ServletException(e);

 

        } catch (SAXException e) {

            log.error(internal.getMessage("configWebXml"), e);

            throw new ServletException(e);

 

        } finally {

            try {

                // 解析完畢,關(guān)閉輸入

input.close();

            } catch (IOException e) {

                log.error(internal.getMessage("configWebXml"), e);

    /**           

如果有異常,當(dāng)前部進行處理,而是留給他的調(diào)用者來處理。其實是當(dāng)前的調(diào)用部分沒有處理的能力。我們可以這樣理解,假設(shè)你想在出現(xiàn)了這類異常異常的地方給用戶一個提示,但是在我們封裝功能實現(xiàn)的時候,我們并不知道誰會來調(diào)用,所以我們只有把異常拋出,讓調(diào)用者自己去處理。

    這一點也許不太好理解,不過,如果理解了,可能你就能夠靈活的使用異常了。

*/

throw new ServletException(e);

            }

        }

 

        // Record a servlet context attribute (if appropriate)

        if (log.isDebugEnabled()) {

            log.debug("Mapping for servlet ‘" + servletName + "‘ = ‘" +

                servletMapping + "‘");

        }

 

        if (servletMapping != null) {

            getServletContext().setAttribute(Globals.SERVLET_KEY, servletMapping);

        }

 

    }

[7] 初始化其他模塊

(1)   初始化工廠

            getServletContext().setAttribute( Globals . ACTION_SERVLET_KEY , this );

            initModuleConfigFactory();

(2)   初始化資源模塊

            // Initialize modules as needed

            ModuleConfig moduleConfig = initModuleConfig( "" , config );

             initModuleMessageResources(moduleConfig);

(3)   初始化數(shù)據(jù)源配置模塊

            initModuleDataSources(moduleConfig);

(4)   初始化 PlugIn 模塊

            initModulePlugIns(moduleConfig);

            moduleConfig.freeze();

[8]   初始化參數(shù)

            Enumeration names = getServletConfig().getInitParameterNames();

            while (names.hasMoreElements()) {

                String name = (String) names.nextElement();

                if (!name.startsWith("config/")) {

                    continue;

                }

                String prefix = name.substring(6);

                moduleConfig = initModuleConfig

                    (prefix, getServletConfig().getInitParameter(name));

                initModuleMessageResources(moduleConfig);

                initModuleDataSources(moduleConfig);

                initModulePlugIns(moduleConfig);

                moduleConfig.freeze();

            }

[9]   我也不知道做什么用的    

            this .initModulePrefixes( this .getServletContext());

   

            this .destroyConfigDigester();

以上就是Struts的初始化流程。

[10]          部分模塊的詳細實現(xiàn):

a.       工廠的初始化如何實現(xiàn)的:

    /**

     * <p>Initialize the factory used to create the module configuration.</p>

     * @since Struts 1.2

     */

protected void initModuleConfigFactory(){

/**

這個部分的代碼就是取得參數(shù)。

這個參數(shù)你可以自己擴展你的模塊實現(xiàn)工廠。但是一般都沒有自己去做。

所以一般都使用的默認的工廠初始化配置。

*/

        String configFactory = getServletConfig().getInitParameter("configFactory");

/**

下面的代碼,只有你做了自己的配置才會有效。否則一般是不執(zhí)行的。

*/

        if (configFactory != null) {

/**

設(shè)置此工廠,并把其參數(shù)存入到 ModuleConfigFactory.factoryClass 屬性中。

此部分可以看 ModuleConfigFactory 的代碼。 ModuleConfigFactory 是一個

*/

            ModuleConfigFactory.setFactoryClass(configFactory);

        }

    }

b.       資源模塊式如何初始化的

// 調(diào)用的部分

protected String config = "/WEB-INF/struts-config.xml";

------------------------------------------------------------------          

ModuleConfig moduleConfig = initModuleConfig("", config);

initModuleMessageResources(moduleConfig);

       // 實現(xiàn)的部分:

    protected void initModuleMessageResources (ModuleConfig config)

        throws ServletException {

              /**

       struts-config.xml 中的資源文件配置,你可能配置了多個資源,所以此處取得是一個數(shù)組

*/

        MessageResourcesConfig mrcs[] = config.findMessageResourcesConfigs();

 

        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()

                        + "‘");

            }

/**

           protected String factory =

        "org.apache.struts.util.PropertyMessageResourcesFactory";

就是返回的這個值,如果你沒有做其他的設(shè)置的話。

一般情況下,我們都用得是默認的

*/

            String factory = mrcs[i].getFactory();

/**

       此處對每一個資源配置文件都回去創(chuàng)建一個工廠

*/

            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());

 

       /**

這一部分非常重要。

我們之所以能夠直接調(diào)用,就是因為,初始化后,我們就把此 resources 放到了其對應(yīng)的當(dāng)前應(yīng)用的屬性值里面了。之后我們就可以直接調(diào)用了。
       */

            getServletContext().setAttribute(

                mrcs[i].getKey() + config.getPrefix(),

                resources);

        }

 

    }

c.       數(shù)據(jù)模塊是如何初始化的

==========================================================

// 調(diào)用部分

initModuleDataSources(moduleConfig);

 

// 實現(xiàn)部分:

/**

     * <p>Initialize the data sources for the specified module.</p>

     *

     * @param config ModuleConfig information for this module

     *

     * @exception ServletException if initialization cannot be performed

     * @since Struts 1.1

     */

    protected void initModuleDataSources(ModuleConfig config) throws ServletException {

 

        // :FIXME: Document UnavailableException?

 

        if (log.isDebugEnabled()) {

            log.debug("Initializing module path ‘" + config.getPrefix() +

                "‘ data sources");

        }

 

        ServletContextWriter scw =

            new ServletContextWriter(getServletContext());

/**

因為你可能配置了多個數(shù)據(jù)源,所以此處返回的是一個數(shù)組
*/

        DataSourceConfig dscs[] = config.findDataSourceConfigs();

    // 處理沒有配置數(shù)據(jù)源的情況

if (dscs == null) {

dscs = new DataSourceConfig[0];

        }

/**

           /**

     * <p>The JDBC data sources that has been configured for this module,

     * if any, keyed by the servlet context attribute under which they are

     * stored.</p>

     */

protected FastHashMap dataSources = new FastHashMap();

這是一個加工過的 HashMap ,又不同的工作模式

 

*/

 

        dataSources.setFast(false);

        for (int i = 0; i < dscs.length; i++) {

            if (log.isDebugEnabled()) {

                log.debug("Initializing module path ‘" + config.getPrefix() +

                    "‘ data source ‘" + dscs[i].getKey() + "‘");

            }

            DataSource ds = null;

            try {

          /**

*/

   ds = (DataSource)

                    RequestUtils.applicationInstance(dscs[i].getType());

                BeanUtils.populate(ds, dscs[i].getProperties());

                ds.setLogWriter(scw);

 

            } catch (Exception e) {

                log.error(internal.getMessage("dataSource.init", dscs[i].getKey()), e);

                throw new UnavailableException

                    (internal.getMessage("dataSource.init", dscs[i].getKey()));

            }

/**

       這一個部分很重要。

       把初始化后的數(shù)據(jù)源放入到 servlet 的屬性中,所以我們才可以通過 struts 的對應(yīng)屬性直接訪問。

  protected String key = Globals.DATA_SOURCE_KEY;

所以,我們可以通過 Globals.DATA_SOURCE_KEY 屬性的值來取得其配制后的數(shù)據(jù)源。

如果多個的話,可以通過數(shù)據(jù)源的參數(shù) ID 來配置和調(diào)用。

*/

            getServletContext().setAttribute

                (dscs[i].getKey() + config.getPrefix(), ds);

            dataSources.put(dscs[i].getKey(), ds);

        }

 

        dataSources.setFast(true);

 

    }

 

至此,Struts系統(tǒng)初始化完畢。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
JR 精品文章 - 使用Timmer使Struts修改struts-config.xml文...
Matrix - 與 Java 共舞 - 開始使用Commons Chain(第二部分)
struts源代碼閱讀(struts 初始化)
Spring、Hibernate、Struts1整合的方式
"struts中文問題","struts國際化問題"的終極解決方案
SSH面試題
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服