<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 188,comments - 176,trackbacks - 0

      

        struts 的核心類是org.apache.struts.action.ActionServlet,這個類將會在struts第一次使用時,
    作為servlet初始化并存入tomcat容器。很顯然的,初始化將會調用init方法初始化相應的數據。

     

    一、initInternal()方法:


        通過調用MessageResources.getMessageResources(internalName)方法生成一個
        MessageResources類,getMessageResources是通過調用MessageResourcesFactory.
        createResources(config)來實現的。至于MessageResourcesFactory是一個abstract類,任何
        繼承自它的類都要實現createResources方法,生成MessageResources對象。整個程序生成
        MessageResourcesFactory使用了如下技巧:
        MessageResourcesFactory.factoryClass = factoryClass;
        MessageResourcesFactory.clazz = null;
        首先會通過factoryClass來定義一個類全名,然后通過ClassLoader.loadClass
        (factoryClass)方法來生成這個類,并賦給clazz,然后通過newInstance來生成一個對象。
        在本程序中,生成MessageResources對象實際就是對如下屬性進行了初始化:
        this.factory = factory;("org.apache.struts.util.PropertyMessageResourcesFactory")
        this.config = config;("org.apache.struts.action.ActionResources")
        this.returnNull = returnNull;(true/false)

        對于MessageResources類的作用是根據不同的Locate來格式化相應的string?;蛘甙涯阈枰淖?br>    的string存放到數組中,然后通過getMessage(Locale locale, String key, Object args[])
        方法來格式化。然后把格式好的string存放到HashMap里,這樣就可以為以后重用。這里的key是
        使用的locale.toString() + "." + key

        在PropertyMessageResources中的loadLocale方法用來讀取resource的初始化信息。首先它會
        通過一個HashMap檢測這個localKey相關的message是否已經被初始化了,如果被初始化過就跳
        出,檢測的方法是locales.get(localeKey) != null。
        然后會讀取如下一個文件:
        org/apache/struts/action/ActionResources_(localKey).properties,然后進行如下操作:
        Properties props = new Properties();
        ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
        is = classLoader.getResourceAsStream(name);
        props.load(is);
        Iterator names = props.keySet().iterator();
            while (names.hasNext()) {
                String key = (String) names.next();
                if (log.isTraceEnabled()) {
                    log.trace("  Saving message key '" + messageKey(localeKey, key));
                }
                messages.put(messageKey(localeKey, key), props.getProperty(key));
        }

        PropertyMessageResources 就是通過上面的loadLocale方法查找與Locale locale, String key
        相對對應的Message.查找的次序如下locale.toString(),然后是
        localeKey = localeKey.substring(0, underscore),然后是defaultLocale,然后是key。

        最后,resource類的結構如下:
        PropertyMessageResources extends MessageResources
        PropertyMessageResourcesFactory extends MessageResourcesFactory

     

    二、initOther()方法:


        從servlet中獲取config和debug兩個參數,然后初始化ConvertUtils對象。由于
        ConvertUtils.deregister()的初始化,所有的Converter都是有初始值的,所以這里Struts自己
        把這些初始值設置為null,即轉換出錯的時候返回null,而不是初始值。使用ConvertUtils類的
        原因是由于從form傳輸過來的都是String類型的值,所以我們要把它們轉換成相應的類型。

        提到幾個技巧:
        *public boolean isIndexed() {
             if (type == null) {
                 return (false);
             //技巧一:判斷是否是一個Array類的方法
             } else if (type.isArray()) {
                 return (true);
             //技巧二:判斷type是否是List的一個父類或者父接口,或者與List為同一個類
             //要注意如果List是另一個primitive的TYPE類,那么type必須也是這個類才會
             //返回true,否則都是false。注意long.TYPE與Long.class是不同的
             } else if (List.class.isAssignableFrom(type)) {
                 return (true);
             } else {
                return (false);
             }
         }

        *//componentType為Array類所存儲的元素的類別
         Class componentType = indexedProperty.getClass().getComponentType();
         //生成一個新的Array
         Object newArray = Array.newInstance(componentType, (index + 1));
         System.arraycopy(indexedProperty, 0, newArray, 0, length);
         indexedProperty = newArray;
         set(name, indexedProperty);
         int newLength = Array.getLength(indexedProperty);
         for (int i = length; i < newLength; i++) {
            Array.set(indexedProperty, i, createProperty(name+"["+i+"]", componentType));
         }

     

    三、initServlet()方法:


        這個方法主要是通過digester類解析web.xml,對String servletMapping屬性進行初始化。對于
        digester說明如下:這是一個基于DOM的SAX實現的類,它是事件觸發的,根據xml文件的結構,
        每次讀到一個節點元素就會觸發一個事件。

        InputStream input = getServletContext().getResourceAsStream("/WEB-INF/web.xml");
        這是一個比較少見的方法。首先通過this.servletName = getServletConfig().
        getServletName()獲取servlet的名稱,然后根據
        if (servletName.equals(this.servletName)) {
            this.servletMapping = urlPattern;
        }
        來判斷當前讀到的servlet名稱是否是我們運行的servlet的名稱,如果是,就把url-pattern作為
        我們的servletMapping。

     

    四、getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this)


        把自己存儲到servletContext中,屬性名為Globals.ACTION_SERVLET_KEY。

     

    五、ModuleConfig moduleConfig = initModuleConfig("", config)


        這個方法使用由initOther()方法獲取的config值為要解析的xml路徑,用來初始化ModuleConfig。
        它首先采用與生成MessageResourcesFactory同樣的方法產生一個MessageResourcesFactory對象:
        MessageResourcesFactory為一個抽象類,每一個繼承它的類都要實現
        createModuleConfig(String prefix)方法。本程序使用的缺省的MessageResourcesFactory類為
        org.apache.struts.config.impl.DefaultModuleConfigFactory,它的createModuleConfig(String prefix)方法會生成一個ModuleConfigImpl類。ModuleConfigImpl類相當于一個JavaBean,用來存放一個web模塊運行時所需要的配置信息。當然,一個web模塊可以擁有多個ModuleConfig,但是缺省的是prefix長度為0的ModuleConifg。它的每個屬性幾乎都是由HashMap組成的,它通過一個configured布爾值來描述當前的ModuleConfig是否已經被初始化完畢,在每存放一個屬性的時候都會監測這個值。如果初始化完畢而還要改變里面的屬性值,則會報出IllegalStateException("Configuration is frozen")異常,現在對它的屬性簡單說明如下:


        * protected HashMap actionConfigs:
          這個HashMap用來存儲ActionConfig對象。
        * protected HashMap dataSources
          這個HashMap用來存儲DataSourceConfig對象。
        * protected HashMap exceptions
          這個HashMap用來存儲ExceptionConfig對象。
        * protected HashMap formBeans
          這個HashMap用來存儲FormBeanConfig對象。
        * protected HashMap forwards
          這個HashMap用來存儲ForwardConfig對象。
        * protected HashMap messageResources
          這個HashMap用來存儲MessageResourcesConfig對象。
        * protected ArrayList plugIns
          這個HashMap用來存儲PlugInConfig對象。
        * protected ControllerConfig controllerConfig
          ControllerConfig類
        * protected boolean configured
          標志這個ModuleConfig是(true)否(false)配置完成。
        * protected String prefix
          用來標志和區分ModuleConfig類,同時在使用上面的config類初始化相應的資源以后,也是通
          過這個prefix來區分所屬的不同的web模塊。
        * protected String actionMappingClass = "org.apache.struts.action.ActionMapping"
          ActionMapping類名,缺省為org.apache.struts.action.ActionMapping。

        初始化ModuleConfig的方法如下:
        首先是使用getServletConfig().getInitParameter("mapping")來獲取設定的ActionMapping類
        名,然后通過initConfigDigester()方法來生成一個digester。最后用","分隔config,對每一
        塊調用parseModuleConfigFile(prefix, paths, config, digester, path)方法解析。注意,這
        個方法實際上只有兩個參數是有意義的:path為我們要解析的xml文件,config用來初始化完成
        后保存到servletContext中。

        如果ModuleConfig中存放的FormBeanConfig為Dydamic類型,那么就調用
        DynaActionFormClass.createDynaActionFormClass(FormBeanConfig)初始化
        DynaActionFormClass,并存放到DynaActionFormClass.dynaClasses 的 static HashMap中。這里的key為FormBeanConfig.getName() + moduleConfig.getPrefix()。
       
        如果當前的ModuleConfig為缺省的ModuleConfig,那么將會調用如下幾個方法:
        defaultControllerConfig(config)
        defaultMessageResourcesConfig(config)
        defaultFormBeansConfig(config)
        defaultForwardsConfig(config)
        defaultMappingsConfig(config)
        在struts1.1以后,這個特例將會被廢棄:

        defaultControllerConfig(config)為ControllerConfig通過getInitParameter(s)方法初始化如
        下幾個屬性:bufferSize,content,locale(true/false),maxFileSize,nocache(true/false)
        ,multipartClass,tempDir。defaultMessageResourcesConfig(config)為MessageResourcesConfig通過getInitParameter(s)方法初始化如下幾個屬性:application,factory,null(true/false)。

        其它的幾個方法就是獲取不同的對象,然后把它們相應的存儲到servlet中。關心如下:
        ActionFormBeans=>FormBeanConfig,ActionForwards=>ForwardConfig,
        ActionMappings=>ActionConfig。

     

    六、initModuleMessageResources(ModuleConfig config)


        通過存儲在ModuleConfig中的MessageResourcesConfig對象,逐個初始化MessageResource,
        然后再把初始化好的MessageResources存放到ServletContext中,attributeName為
        MessageResourcesConfig.getKey() + ModuleConfig.getPrefix()。

     

    七、initModuleDataSources(ModuleConfig config)


        通過存儲在ModuleConfig中的DataSourceConfig對象,逐個初始化DataSource。然后對于每一個DateSource通過BeanUtils.populate(ds, dscs[i].getProperties())方法初始化其屬性。再把初始化好的DateSource存放到ServletContext中attributeNameDataSourceConfig.getKey() + ModuleConfig.getPrefix()。同時也存放到名位dataSources的FastHashMap中,key為DataSourceConfig.getKey()。

    這里還會根據生成的DateSource對象是否是GenericDataSource類型,如果是則調用GenericDataSource.open()方法。GenericDataSource是一個非常簡單的數據庫連接池,它的open()方法用來初始化連接池,生成最小數目的GenericConnection,這里的open()方法根據String driver

    變量是否為null來判斷是否已經被初始化過。需要仔細說明的是getConnection()方法,它首先從連接池中取出GenericConnection對象,然后

    檢查其是否是可鏈接的,如果是就返回,否則繼續取出,同時activeCount-1。如果沒有取到,則會檢查當前可使用的GenericConnection是否

    達到最大值(activeCount < maxCount),如果沒有,調用createConnection()方法聲成一個新的GenericConnection,然后檢查其是否是可鏈接

    ,如果可以則返回。returnConnection(GenericConnection conn)方法則是通過把GenericConnection放回到連接池,然后activeCount-1。 這

    個方法中使用到了ServletContextWriter類,DateSource的log信息就通過這個類寫入。對這個類說明如下:它繼承自PrintWriter,而

    PrintWriter又繼承自Writer。Writer類所作的事情就是在同步的情況下調用abstract方法:abstract public void write(char cbuf[], int

    off, int len),這個方法將會根據調用者的需要由調用者實現。PrintWriter則首先通過ensureOpen()方法檢驗這個類中是否有寫入的對象

    (Writer類或其子類),如果有則根據不同的情況調用這個寫入對象的write方法(out.write(....))。這個類的print(...)方法就是據不同的情

    況調用相應的write(...)方法。而println(...)與之的區別就是每次多寫入一個換行字符串。還有一個區別是println(...)會根據是否需要

    autoflush進行flush,而write(...)方法不會。
        ServletContextWriter類的作用是把字符寫入ServletContext中。ServletContextWriter類方法中真正實現了write方法:
        public void write(char c) {
            if (c == '\n')
                flush();
            else if (c != '\r')
                buffer.append(c);
        }
        public void flush() {
            if (buffer.length() > 0) {
                context.log(buffer.toString());
                buffer.setLength(0);
            }
        }

     

     

    八、initModulePlugIns(moduleConfig)


        通過存儲在ModuleConfig中的PlugInConfig對象,逐個初始化PlugIn對象,存放到一個數組中,
        然后再把這個數組存放到ServletContext中,attributeName為
        Globals.PLUG_INS_KEY + ModuleConfig.getPrefix()。

        對每一個生成的PlugIn對象通過
        BeanUtils.populate(plugIns[i], plugInConfigs[i].getProperties())方法初始化其屬性。然后
        再把PlugInConfig對象存放到由其生成的PlugIn對象中。

        最后,通過plugIns[i].init(this, (ModuleConfig) config)初始化這個plugIn對象。

     

    九、初始化結束


        完成了這個初始化以后,會調用ModuleConfig.freeze()令這個ModuleConfig變得不可改變。然后
        會遍歷ServletConfig中的initParameterNames,如果有以"config/"開頭的,則通過這個parameter
        的值繼續初始化其它的ModuleConfig,且這個ModuleConfig的prefix為"config/"后的字符串。
       
        同樣調用如下方法:
        initModuleMessageResources(moduleConfig);
        initModuleDataSources(moduleConfig);
        initModulePlugIns(moduleConfig);
        moduleConfig.freeze();

        最后調用destroyConfigDigester()釋放內存。


    轉CSDN

    posted on 2007-05-24 11:29 cheng 閱讀(546) 評論(0)  編輯  收藏 所屬分類: Struts
    主站蜘蛛池模板: 日本亚洲国产一区二区三区| 在线精品免费视频| 亚洲国产精品VA在线观看麻豆| 中文字幕手机在线免费看电影| 亚洲狠狠婷婷综合久久久久| 9久9久女女免费精品视频在线观看 | 久久精品亚洲综合| 老司机永久免费网站在线观看| 2022免费国产精品福利在线| 亚洲精品无码不卡在线播放| 亚洲免费在线视频观看| 亚洲一区二区无码偷拍| 中文字幕不卡亚洲| 国产综合亚洲专区在线| 久久亚洲国产成人精品无码区| 可以免费看黄的网站| 国产免费内射又粗又爽密桃视频| 亚洲乱妇熟女爽到高潮的片| 亚洲av无码专区在线观看下载| 亚洲欧洲日产国产综合网| 国产精品jizz在线观看免费| 成年女人色毛片免费看| 久久久亚洲AV波多野结衣| 亚洲高清免费视频| 97热久久免费频精品99| 大妹子影视剧在线观看全集免费| 久久性生大片免费观看性| 久久免费视频观看| 黄页视频在线观看免费| 久久免费视频99| 亚洲欧洲国产成人精品| 亚洲日韩精品一区二区三区无码 | h在线观看视频免费网站| 100000免费啪啪18免进| 狠狠久久永久免费观看| 亚洲精品无码av天堂| 日韩一区二区三区免费体验| 日韩一区二区a片免费观看 | caoporm碰最新免费公开视频 | 精品国产成人亚洲午夜福利| 女人被男人躁的女爽免费视频|