亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

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

系統 2111 0

第十七課: StandardWrapper

課前復習:

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

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

1. ?????? Connector 創建 req resp

2. ?????? 調用 StandardContext invoke ,調用 xxxPipeline invoke 方法

3. ?????? Pipeline 調用了 wrapper invoke 方法

4. ?????? Wrapper 調用 valve invoke 方法

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

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

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

關于 SingleThreadModel

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

StandardWrapper

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

?????? 代碼如下。

?

          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 里的一樣,都是調用的 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的內部內容,名稱以org.apache.catalina.起始。之后就是加載servlet,之后就是權限驗證,沒啥說的。在之后就是在init()的前后fire事件。之后用instanceof來確定是否是實現了singleThreadModel的,如果是就放入pool(如果pool為空就創建一個新的)中。剩下就是Return了。

?



ServletConfig

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

?

Filter

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

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

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

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

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

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

?

?

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


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

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

【本文對您有幫助就好】

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

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 91视频免费观看 | 老子影院午夜伦手机在线看 | 射婷婷| 极品美女一级毛片 | 色视频亚洲 | 手机看片福利日韩国产 | 亚洲国产小视频 | 一级毛片视频在线 | 亚洲欧美另类在线观看 | 亚洲天天做夜夜做天天欢人人 | 欧美日韩中文国产一区 | 久久精品这里热有精品 | 操bb影院 | 亚拍精品一区二区三区 | 99热这里只有精品一区二 | 看免费的毛片 | 老司机福利精品 | 97在线观看视频免费 | 日本不卡视频免费 | 国产成+人+综合+欧美 亚洲 | 男人天堂2021| 99久久久精品免费观看国产 | 日日操狠狠操 | 免费爱爱 | 久久99精品久久久久久国产越南 | 四虎私人影院 | 欧美精品亚洲精品日韩经典 | 久久97久久97精品免视看 | 欧美色大成网站www永久男同 | 深夜福利国产福利视频 | 国内自拍一二三四2021 | www.久久色 | 欧洲国产伦久久久久久久 | 99精品国产成人一区二区在线 | 国产深夜福利视频在线观看 | 欧美久久天天综合香蕉伊 | 91在线看片一区国产 | 亚洲国产日韩综合久久精品 | 色片网站在线观看 | 久久99国产亚洲精品 | 99热网站 |