欧美三区_成人在线免费观看视频_欧美极品少妇xxxxⅹ免费视频_a级毛片免费播放_鲁一鲁中文字幕久久_亚洲一级特黄

Tomcat從零開始(十七)——StandardWrapper

系統(tǒng) 1916 0

第十七課: StandardWrapper

課前復習:

?????? 不知道大家是否還有印象,就是在 6 7 節(jié)課說的 4 container, 粗略的從大到小來說就是 engine,host,context , wrapper 。當時寫的時候很糾結(jié),因為后面有詳細介紹這 4 個的計劃,所以前面寫的可能不是很詳盡。

?????? 讓我們回憶一下,當一個請求到來的時候,發(fā)生了什么。比如什么創(chuàng)建 Request 這里就不說了,之后 connector 會調(diào)用與之關聯(lián)的容器的 invoke 方法,之后那就肯定會調(diào)用 pipeline invoke ,之后一頓 invoke valve 。好,那讓我們回想一下之前寫過的 context wrapper ,總結(jié)一個比較詳細的執(zhí)行過程。

1. ?????? Connector 創(chuàng)建 req resp

2. ?????? 調(diào)用 StandardContext invoke ,調(diào)用 xxxPipeline invoke 方法

3. ?????? Pipeline 調(diào)用了 wrapper invoke 方法

4. ?????? Wrapper 調(diào)用 valve invoke 方法

5. ?????? valve 調(diào)用了 servlet allocate (這里在以前的課程中講過)

6. ?????? allocate 方法調(diào)用 servlet load 方法 ( servlet 需要加載的時候 )

7. ?????? init 方法,之后就是 servlet 處理了。

關于 SingleThreadModel

?????? 這個 SingleThreadModel servlet2.4 以上版本就已經(jīng)移除了,因為這個東西只能給你的 servlet service 保證同一時刻只有一個進程在訪問,給人一種假象的安全。而且只是給 service 方法給予同步,這顯然是不能完全解決多線程訪問的問題的。其實說這個是為了給下面的 StandardWrapper 做鋪墊。因為我們都知道 StrandardWrapper 是負責加載它所代表的 servlet allocate 一個對象的實例。之后交給 valve 來調(diào)用 servlet service 方法。這個 allocate 在使用 不使用 SingleThreadModel 的時候是不同的。好的,我們接下來就說這個 StandardWrapper

StandardWrapper

?????? 這個之前介紹過了,我們這次主要介紹的是 allocate 方法, 我們看下面這一段源碼可以發(fā)現(xiàn),當沒有實現(xiàn) SingleThreadModel 的時候, allocate 總是返回第一次時候產(chǎn)生的 servlet 實例。而如果實現(xiàn) SingleThreadModel 接口,那么就開始控制分配的數(shù)量,當分配的大于 nInstance 時候,就 load 一個 servlet 實例,當然這個 load 實在 maxInstance 控制之內(nèi)的。

?????? 代碼如下。

?

          public Servlet allocate() throws ServletException {

        if (debug >= 1)
            log("Allocating an instance");

        // If we are currently unloading this servlet, throw an exception
        if (unloading)
            throw new ServletException
              (sm.getString("standardWrapper.unloading", getName()));

        // If not SingleThreadedModel, return the same instance every time
        if (!singleThreadModel) {

            // Load and initialize our instance if necessary
            if (instance == null) {
                synchronized (this) {
                    if (instance == null) {
                        try {
                            instance = loadServlet();
                        } catch (ServletException e) {
                            throw e;
                        } catch (Throwable e) {
                            throw new ServletException
                                (sm.getString("standardWrapper.allocate"), e);
                        }
                    }
                }
            }

            if (!singleThreadModel) {
                if (debug >= 2)
                    log("  Returning non-STM instance");
                countAllocated++;
                return (instance);
            }

        }

        synchronized (instancePool) {

            while (countAllocated >= nInstances) {
                // Allocate a new instance if possible, or else wait
                if (nInstances < maxInstances) {
                    try {
                        instancePool.push(loadServlet());
                        nInstances++;
                    } catch (ServletException e) {
                        throw e;
                    } catch (Throwable e) {
                        throw new ServletException
                            (sm.getString("standardWrapper.allocate"), e);
                    }
                } else {
                    try {
                        instancePool.wait();
                    } catch (InterruptedException e) {
                        ;
                    }
                }
            }
            if (debug >= 2)
                log("  Returning allocated STM instance");
            countAllocated++;
            return (Servlet) instancePool.pop();

        }

    }
    

?

Load

?????? 這個沒什么多說的,以前說過了,我們知道 wrapper 接口有一個 load 方法,其實他和 Allocate 里的一樣,都是調(diào)用的 LoadServlet 方法。我們來看看它的源碼。

? ? 先看看這一段。

?

              // 這里是說如果不是第一次訪問了,并且不是singleThreadModel
    	//就直接返回  Servlet實例
        if (!singleThreadModel && (instance != null))
            return instance;

	if ((actualClass == null) && (jspFile != null)) {
                Wrapper jspWrapper = (Wrapper)
                    ((Context) getParent()).findChild(Constants.JSP_SERVLET_NAME);
                if (jspWrapper != null) {
                    actualClass = jspWrapper.getServletClass();
                    // Merge init parameters
                    String paramNames[] = jspWrapper.findInitParameters();
                    for (int i = 0; i < paramNames.length; i++) {
                        if (parameters.get(paramNames[i]) == null) {
                            parameters.put
                                (paramNames[i], 
                            jspWrapper.findInitParameter(paramNames[i]));
                        }
                    }
                }
}

    
? ? ?這是Tomcat4 的方法,以后的版本就沒有了。都是直接loadservletclass。之后就是Loader了,回憶一下我們當時講的,是自定義的一個classLoader,需要注意的是,container提供一個特殊的servlet,可以訪問container的內(nèi)部內(nèi)容,名稱以org.apache.catalina.起始。之后就是加載servlet,之后就是權(quán)限驗證,沒啥說的。在之后就是在init()的前后fire事件。之后用instanceof來確定是否是實現(xiàn)了singleThreadModel的,如果是就放入pool(如果pool為空就創(chuàng)建一個新的)中。剩下就是Return了。

?



ServletConfig

?????? 接下來就是 servletConfig ,這個東西我們回憶一下是在哪里看到這個東西的,想想在 servlet load 的時候,就會調(diào)用一個 init 方法,而且他的參數(shù)是 ServletConfig config ,那么,我們就需要知道 servlet 是怎么拿到 servletConfig 的,我們看源碼,會發(fā)現(xiàn) StandardWrapper 他實現(xiàn)了 ServletConfig 接口,所以說他把自己傳過去就行了。但是想一個事情,如果這樣可以,那么 servlet 的每一個實現(xiàn)就都可以用 wrapper 之內(nèi)的方法了, wrapper container 的,所以我們要保證安全,那么就像 req,resp 那樣,用一個 fa?ade 設計模式就行,這個就是隱藏子系統(tǒng)。

?

Filter

?????? 做過 web 開發(fā),大家應該知道 filter 這個東西,那么 filter 是怎么實現(xiàn)的呢,我們想一下之前學的東西,我們應該能想到 ServletWrapperValve 做了這件事情,因為 filter 是跟 service 方法前后后關系。那么我們就可以知道 valve invoke 方法做了什么:

1. ?????? 首先要得到一個 wrapper 的對象, allocate 一個 servlet

2. ?????? 來一系列的 Filter ,調(diào)用他們的 doFilter 方法,當然還有 service 方法

3. ?????? 銷毀,這個應該是在 servlet 超時的時候才進行。

剩下就是講解一下 filter chain 了,這個東西其實是一個 ArrayList ,但是注意 filterChain 是一個對象,其中的 filter 是一個該對象之中的一個 arraylist, 所以我們就知道,這個東西其實就是靠 iterator 來實現(xiàn)一個接一個的調(diào)用過濾器。所以,本章就結(jié)束了,這章其實沒有多少自己寫的東西,基本都是對源代碼的一種分析,希望大家可以多理解,或者下一個 tomcat sourcecode 版本,之后多用斷點 跑一跑就能理解是怎么工作的了。

? ? 最后還是冒充一下大神說說讀代碼的事吧,剛才有人問了問為啥我能讀懂一些,剛開始的時候我也看不懂,其實就是你最開始看的時候不要糾結(jié)于所有的語句,至少你能看懂這個方法主要是干啥功能的,大概哪幾個語句能實現(xiàn)就行了,等你慢慢的看完這個,再看完另一個,你就能知道到底那個語句是干什么的了。

?

?

Tomcat從零開始(十七)——StandardWrapper


更多文章、技術交流、商務合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 成人18免费入口 | 欧美经典成人在观看线视频 | 国产成人精品在线 | 精品日本三级在线观看视频 | 久久这里只有精品国产99 | 久久亚洲国产成人亚 | 亚洲人成在线观看一区二区 | 欧美精品免费线视频观看视频 | 看黄色一级视频 | 久草网在线观看 | 国产一区在线免费观看 | 蜜芽在线 | 国产精品一区二区免费 | hdbbwsexvideo| 九色网址 | 九九精品视频一区二区三区 | 毛片网此 | 东方亚洲东方欧美色二区 | 91福利一区二区在线观看 | 性69式视频在线观看免费 | 91亚瑟视频 | 国产乱在线观看视频 | 色3344| 国产成人综合一区二区三区 | 欧美两性网 | 特黄特色大片免费视频观看 | 欧美不卡一区二区三区免 | 日本欧美一区二区三区视频麻豆 | 黑粗硬大欧美 | 国产午夜福利视频一区二区32页 | 中国明星一级毛片免费 | 草草视频在线观看 | 成人午夜AV亚洲精品无码网站 | 国产精品久久久久久影视 | 国产午夜小视频 | 免费观看黄色小视频 | 瑟瑟网站免费网站入口 | 久久久久性视频 | 奇米777在线观看 | 日本一道一区二区免费看 | 日本精品久久久久中文字幕 |