欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費電子書(shū)等14項超值服

開(kāi)通VIP
struts源代碼閱讀(struts 初始化)

struts源代碼閱讀(struts 初始化)- -

                                      

我在幾個(gè)月前曾經(jīng)發(fā)表過(guò)一個(gè)帖子,就是和大家一起學(xué)習struts源代碼。成為一名合格的程序員,閱讀大量的優(yōu)秀程序是必不可少的。只看書(shū)是不會(huì )讓你水平有很大提高的,要多看多寫(xiě)。
本來(lái)是打算等下面幾篇文章寫(xiě)好后一起發(fā)布的,這樣大家可能才能看得明白些,但是根據我現在的狀況,估計還要一、兩個(gè)月。所以,為了防止在struts源代碼發(fā)生過(guò)大變化后我的文章就沒(méi)有太大價(jià)值了,所以就提前發(fā)表了,霍霍~(yú)~~
我的email為:mariah_fan@hotmail.com,有什么不對的地方請大家指正:)
struts作為J2EE的MVC框架已經(jīng)取得了很大的成功,下面將分幾篇文章說(shuō)明struts源程序的結構。
第一篇  struts的初始化

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

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

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

    在PropertyMessageResources中的loadLocale方法用來(lái)讀取resource的初始化信息。首先它會(huì )
    通過(guò)一個(gè)HashMap檢測這個(gè)localKey相關(guān)的message是否已經(jīng)被初始化了,如果被初始化過(guò)就跳
    出,檢測的方法是locales.get(localeKey) != null。
    然后會(huì )讀取如下一個(gè)文件:
    org/apache/struts/action/ActionResources_(localKey).properties,然后進(jìn)行如下操作:
    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 就是通過(guò)上面的loadLocale方法查找與Locale locale, String key
    相對對應的Message.查找的次序如下locale.toString(),然后是
    localeKey = localeKey.substring(0, underscore),然后是defaultLocale,然后是key。

    最后,resource類(lèi)的結構如下:
    PropertyMessageResources extends MessageResources
    PropertyMessageResourcesFactory extends MessageResourcesFactory

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

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

    *//componentType為Array類(lèi)所存儲的元素的類(lèi)別 
     Class componentType = indexedProperty.getClass().getComponentType();
     //生成一個(gè)新的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()方法:
    這個(gè)方法主要是通過(guò)digester類(lèi)解析web.xml,對String servletMapping屬性進(jìn)行初始化。對于
    digester說(shuō)明如下:這是一個(gè)基于DOM的SAX實(shí)現的類(lèi),它是事件觸發(fā)的,根據xml文件的結構,
    每次讀到一個(gè)節點(diǎn)元素就會(huì )觸發(fā)一個(gè)事件。

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

四、getServletContext().setAttribute(Globals.ACTION_SERVLET_KEY, this)
    把自己存儲到servletContext中,屬性名為Globals.ACTION_SERVLET_KEY。

五、ModuleConfig moduleConfig = initModuleConfig("", config)
    這個(gè)方法使用由initOther()方法獲取的config值為要解析的xml路徑,用來(lái)初始化ModuleConfig。
    它首先采用與生成MessageResourcesFactory同樣的方法產(chǎn)生一個(gè)MessageResourcesFactory對象:
    MessageResourcesFactory為一個(gè)抽象類(lèi),每一個(gè)繼承它的類(lèi)都要實(shí)現
    createModuleConfig(String prefix)方法。本程序使用的缺省的MessageResourcesFactory類(lèi)為
    org.apache.struts.config.impl.DefaultModuleConfigFactory,它
    的createModuleConfig(String prefix)方法會(huì )生成一個(gè)ModuleConfigImpl類(lèi)。

    ModuleConfigImpl類(lèi)相當于一個(gè)JavaBean,用來(lái)存放一個(gè)web模塊運行時(shí)所需要的配置信息。當
    然,一個(gè)web模塊可以擁有多個(gè)ModuleConfig,但是缺省的是prefix長(cháng)度為0的ModuleConifg。它
    的每個(gè)屬性幾乎都是由HashMap組成的,它通過(guò)一個(gè)configured布爾值來(lái)描述當前的ModuleConfig
    是否已經(jīng)被初始化完畢,在每存放一個(gè)屬性的時(shí)候都會(huì )監測這個(gè)值。如果初始化完畢而還要改變
    里面的屬性值,則會(huì )報出IllegalStateException("Configuration is frozen")異常,現在對它
    的屬性簡(jiǎn)單說(shuō)明如下:
    * protected HashMap actionConfigs:
      這個(gè)HashMap用來(lái)存儲ActionConfig對象。
    * protected HashMap dataSources
      這個(gè)HashMap用來(lái)存儲DataSourceConfig對象。
    * protected HashMap exceptions
      這個(gè)HashMap用來(lái)存儲ExceptionConfig對象。
    * protected HashMap formBeans
      這個(gè)HashMap用來(lái)存儲FormBeanConfig對象。
    * protected HashMap forwards
      這個(gè)HashMap用來(lái)存儲ForwardConfig對象。
    * protected HashMap messageResources
      這個(gè)HashMap用來(lái)存儲MessageResourcesConfig對象。
    * protected ArrayList plugIns
      這個(gè)HashMap用來(lái)存儲PlugInConfig對象。
    * protected ControllerConfig controllerConfig
      ControllerConfig類(lèi)
    * protected boolean configured
      標志這個(gè)ModuleConfig是(true)否(false)配置完成。
    * protected String prefix
      用來(lái)標志和區分ModuleConfig類(lèi),同時(shí)在使用上面的config類(lèi)初始化相應的資源以后,也是通
      過(guò)這個(gè)prefix來(lái)區分所屬的不同的web模塊。
    * protected String actionMappingClass = "org.apache.struts.action.ActionMapping"
      ActionMapping類(lèi)名,缺省為org.apache.struts.action.ActionMapping。

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

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

    defaultControllerConfig(config)為ControllerConfig通過(guò)getInitParameter(s)方法初始化如
    下幾個(gè)屬性:bufferSize,content,locale(true/false),maxFileSize,nocache(true/false)
    ,multipartClass,tempDir。

    defaultMessageResourcesConfig(config)為MessageResourcesConfig通過(guò)getInitParameter(s)
    方法初始化如下幾個(gè)屬性:application,factory,null(true/false)。

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

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

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

    這里還會(huì )根據生成的DateSource對象是否是GenericDataSource類(lèi)型,如果是則調用
    GenericDataSource.open()方法。GenericDataSource是一個(gè)非常簡(jiǎn)單的數據庫連接池,它的
    open()方法用來(lái)初始化連接池,生成最小數目的GenericConnection,這里的open()方法根據
    String driver變量是否為null來(lái)判斷是否已經(jīng)被初始化過(guò)。需要仔細說(shuō)明的是getConnection()
    方法,它首先從連接池中取出GenericConnection對象,然后檢查其是否是可鏈接的,如果是就
    返回,否則繼續取出,同時(shí)activeCount-1。如果沒(méi)有取到,則會(huì )檢查當前可使用的
    GenericConnection是否達到最大值(activeCount < maxCount),如果沒(méi)有,調用
    createConnection()方法聲成一個(gè)新的GenericConnection,然后檢查其是否是可鏈接,如果可以
    則返回。returnConnection(GenericConnection conn)方法則是通過(guò)把GenericConnection放回到
    連接池,然后activeCount-1。

    這個(gè)方法中使用到了ServletContextWriter類(lèi),DateSource的log信息就通過(guò)這個(gè)類(lèi)寫(xiě)入。對這個(gè)
    類(lèi)說(shuō)明如下:
    它繼承自PrintWriter,而PrintWriter又繼承自Writer。Writer類(lèi)所作的事情就是在同步的情況下
    調用abstract方法:abstract public void write(char cbuf[], int off, int len),這個(gè)方法
    將會(huì )根據調用者的需要由調用者實(shí)現。
    PrintWriter則首先通過(guò)ensureOpen()方法檢驗這個(gè)類(lèi)中是否有寫(xiě)入的對象(Writer類(lèi)或其子類(lèi)),
    如果有則根據不同的情況調用這個(gè)寫(xiě)入對象的write方法(out.write(....))。這個(gè)類(lèi)的print(...)
    方法就是據不同的情況調用相應的write(...)方法。而println(...)與之的區別就是每次多寫(xiě)入一
    個(gè)換行字符串。還有一個(gè)區別是println(...)會(huì )根據是否需要autoflush進(jìn)行flush,而write(...)
    方法不會(huì )。
    ServletContextWriter類(lèi)的作用是把字符寫(xiě)入ServletContext中。ServletContextWriter類(lèi)方法中
    真正實(shí)現了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)
    通過(guò)存儲在ModuleConfig中的PlugInConfig對象,逐個(gè)初始化PlugIn對象,存放到一個(gè)數組中,
    然后再把這個(gè)數組存放到ServletContext中,attributeName為
    Globals.PLUG_INS_KEY + ModuleConfig.getPrefix()。

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

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

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

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

from:http://www.matrix.org.cn/article/1071.html

本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請點(diǎn)擊舉報。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
Struts源碼的切片學(xué)習( 二)-資源文件的初始化 - 輪上飛 - BlogJava
Struts的資源文件時(shí)如何初始化的--struts源碼學(xué)習 - 輪上飛 - BlogJa...
Matrix - 與 Java 共舞 - 開(kāi)始使用Commons Chain(第二部分)
SSH面試題
struts源代碼閱讀(struts 的執行)
Struts Message Resources
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導長(cháng)圖 關(guān)注 下載文章
綁定賬號成功
后續可登錄賬號暢享VIP特權!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服

欧美性猛交XXXX免费看蜜桃,成人网18免费韩国,亚洲国产成人精品区综合,欧美日韩一区二区三区高清不卡,亚洲综合一区二区精品久久