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

TOMCAT源碼分析(啟動框架)

系統(tǒng) 2244 0

TOMCAT源碼分析(啟動框架)
前言:
?? 本文是我閱讀了TOMCAT源碼后的一些心得。 主要是講解TOMCAT的系統(tǒng)框架, 以及啟動流程。若有錯漏之處,敬請批評指教!
建議:
?? 畢竟TOMCAT的框架還是比較復(fù)雜的, 單是從文字上理解, 是不那么容易掌握TOMCAT的框架的。 所以得實踐、實踐、再實踐。 建議下載一份TOMCAT的源碼, 調(diào)試通過, 然后單步跟蹤其啟動過程。 如果有不明白的地方, 再來查閱本文, 看是否能得到幫助。 我相信這樣效果以及學(xué)習(xí)速度都會好很多!
??
1. Tomcat的整體框架結(jié)構(gòu)
?? Tomcat的基本框架, 分為4個層次。
?? Top Level Elements:
??? Server
??? Service??
?? Connector
??? HTTP
??? AJP
?? Container
?? Engine
???? Host
?? Context
?? Component?
??? manager
?? logger
?? loader
?? pipeline
?? valve
???????? ...
?? 站在框架的頂層的是Server和Service
?? Server:? 其實就是BackGroud程序, 在Tomcat里面的Server的用處是啟動和監(jiān)聽服務(wù)端事件(諸如重啟、關(guān)閉等命令。 在tomcat的標(biāo)準(zhǔn)配置文件:server.xml里面, 我們可以看到“<Server port="8005" shutdown="SHUTDOWN" debug="0">”這里的"SHUTDOWN"就是server在監(jiān)聽服務(wù)端事件的時候所使用的命令字)
?? Service: 在tomcat里面, service是指一類問題的解決方案。? 通常我們會默認(rèn)使用tomcat提供的:Tomcat-Standalone 模式的service。 在這種方式下的service既給我們提供解析jsp和servlet的服務(wù), 同時也提供給我們解析靜態(tài)文本的服務(wù)。
??
?? Connector: Tomcat都是在容器里面處理問題的, 而容器又到哪里去取得輸入信息呢?
Connector就是專干這個的。 他會把從socket傳遞過來的數(shù)據(jù), 封裝成Request, 傳遞給容器來處理。
?? 通常我們會用到兩種Connector,一種叫http connectoer, 用來傳遞http需求的。 另一種叫AJP, 在我們整合apache與tomcat工作的時候, apache與tomcat之間就是通過這個協(xié)議來互動的。 (說到apache與tomcat的整合工作, 通常我們的目的是為了讓apache 獲取靜態(tài)資源, 而讓tomcat來解析動態(tài)的jsp或者servlet。)
?? Container: 當(dāng)http connector把需求傳遞給頂級的container: Engin的時候, 我們的視線就應(yīng)該移動到Container這個層面來了。
?? 在Container這個層, 我們包含了3種容器: Engin, Host, Context.
?? Engin: 收到service傳遞過來的需求, 處理后, 將結(jié)果返回給service( service 是通過 connector 這個媒介來和Engin互動的 ).
?? Host: Engin收到service傳遞過來的需求后,不會自己處理, 而是交給合適的Host來處理。
Host在這里就是虛擬主機的意思, 通常我們都只會使用一個主機,既“l(fā)ocalhost”本地機來處理。
?? Context: Host接到了從Host傳過來的需求后, 也不會自己處理, 而是交給合適的Context來處理。
?? 比如: < http://127.0.0.1:8080/foo/index.jsp >
???????? < http://127.0.1:8080/bar/index.jsp >
?? 前者交給foo這個Context來處理, 后者交給bar這個Context來處理。
?? 很明顯吧! context的意思其實就是一個web app的意思。
?? 我們通常都會在server.xml里面做這樣的配置
?? <Context path="/foo" docBase="D:/project/foo/web" />
?? 這個context容器,就是用來干我們該干的事兒的地方的。
??
?? Compenent: 接下來, 我們繼續(xù)講講component是干什么用的。
?? 我們得先理解一下容器和組件的關(guān)系。
?? 需求被傳遞到了容器里面, 在合適的時候, 會傳遞給下一個容器處理。
?? 而容器里面又盛裝著各種各樣的組件, 我們可以理解為提供各種各樣的增值服務(wù)。
?? manager: 當(dāng)一個容器里面裝了manager組件后,這個容器就支持session管理了, 事實上在tomcat里面的session管理, 就是靠的在context里面裝的manager component.
?? logger: 當(dāng)一個容器里面裝了logger組件后, 這個容器里所發(fā)生的事情, 就被該組件記錄下來啦! 我們通常會在logs/ 這個目錄下看見 catalina_log.time.txt 以及 localhost.time.txt 和localhost_examples_log.time.txt。 這就是因為我們分別為:engin, host以及context(examples)這三個容器安裝了logger組件, 這也是默認(rèn)安裝, 又叫做標(biāo)配 :)
?? loader: loader這個組件通常只會給我們的context容器使用, loader是用來啟動context以及管理這個context的classloader用的。
??? pipline: pipeline是這樣一個東西, 當(dāng)一個容器決定了要把從上級傳遞過來的需求交給子容器的時候, 他就把這個需求放進(jìn)容器的管道(pipeline)里面去。 而需求傻呼呼得在管道里面流動的時候, 就會被管道里面的各個閥門攔截下來。 比如管道里面放了兩個閥門。 第一個閥門叫做“access_allow_vavle”, 也就是說需求流過來的時候,它會看這個需求是哪個IP過來的, 如果這個IP已經(jīng)在黑名單里面了, sure, 殺! 第二個閥門叫做“defaul_access_valve”它會做例行的檢查, 如果通過的話,OK, 把需求傳遞給當(dāng)前容器的子容器。 就是通過這種方式, 需求就在各個容器里面?zhèn)鬟f,流動, 最后抵達(dá)目的地的了。
??? valve: 就是上面所說的閥門啦。
?? Tomcat里面大概就是這么些東西, 我們可以簡單地這么理解tomcat的框架,它是一種自上而下, 容器里又包含子容器的這樣一種結(jié)構(gòu)。
2. Tomcat的啟動流程
?? 這篇文章是講tomcat怎么啟動的,既然我們大體上了解了TOMCAT的框架結(jié)構(gòu)了, 那么我們可以望文生意地就猜到tomcat的啟動, 會先啟動父容器,然后逐個啟動里面的子容器。 啟動每一個容器的時候, 都會啟動安插在他身上的組件。 當(dāng)所有的組件啟動完畢, 所有的容器啟動完畢的時候, tomcat本身也就啟動完畢了。
?? 順理成章地, 我們同樣可以猜到, tomcat的啟動會分成兩大部分, 第一步是裝配工作。 第二步是啟動工作。
?? 裝配工作就是為父容器裝上子容器, 為各個容器安插進(jìn)組件的工作。 這個地方我們會用到digester模式, 至于digester模式什么, 有什么用, 怎么工作的. 請參考 < http://software.ccidnet.com/pub/article/c322_a31671_p2.html >
?? 啟動工作是在裝配工作之后, 一旦裝配成功了, 我們就只需要點燃最上面的一根導(dǎo)線, 整個tomcat就會被激活起來。 這就好比我們要開一輛已經(jīng)裝配好了的汽車的時候一樣,我們只要把鑰匙插進(jìn)鑰匙孔,一擰,汽車的引擎就會發(fā)動起來,空調(diào)就會開起來, 安全裝置就會生效, 如此一來,汽車整個就發(fā)動起來了。(這個過程確實和TOMCAT的啟動過程不謀而和, 讓我們不得不懷疑 TOMCAT的設(shè)計者是在GE做JAVA開發(fā)的)。
2.1 一些有意思的名稱:
?? Catalina
?? Tomcat
?? Bootstrap
?? Engin
?? Host
?? Context
?? 他們的意思很有意思:
?? Catalina: 遠(yuǎn)程轟炸機
?? Tomcat: 熊貓轟炸機 -- 轟炸機的一種(這讓我想起了讓國人引以為豪的熊貓手機,是不是英文可以叫做tomcat??? , 又讓我想起了另一則廣告: 波導(dǎo)-手機中的戰(zhàn)斗機、波音-客機中的戰(zhàn)斗機 )
?? Bootstap: 引導(dǎo)
?? Engin: 發(fā)動機
?? Host: 主機,領(lǐng)土
?? Context: 內(nèi)容, 目標(biāo), 上下文
??
?? ... 在許多許多年后, 現(xiàn)代人類已經(jīng)滅絕。 后現(xiàn)代生物發(fā)現(xiàn)了這些單詞零落零落在一塊。 一個自以為聰明的家伙把這些東西翻譯出來了:
?? 在地勤人員的引導(dǎo)(bootstrap)下, 一架轟炸架(catalina)騰空躍起, 遠(yuǎn)看是熊貓轟炸機(tomcat), 近看還是熊貓轟炸機! 憑借著優(yōu)秀的發(fā)動機技術(shù)(engin), 這架熊貓轟炸機飛臨了敵國的領(lǐng)土上空(host), 對準(zhǔn)目標(biāo)(context)投下了毀天滅地的核彈頭,波~ 現(xiàn)代生物就這么隔屁了~
?
?? 綜上所述, 這又不得不讓人聯(lián)想到GE是不是也參與了軍事設(shè)備的生產(chǎn)呢?
?? 反對美帝國主義! 反對美霸權(quán)主義! 和平萬歲! 自由萬歲!
??
2.2? 歷史就是那么驚人的相似! tomcat的啟動就是從org.apache.catalina.startup.Bootstrap這個類悍然啟動的!
?? 在Bootstrap里做了兩件事:
?? 1. 指定了3種類型classloader:
????? commonLoader: common/classes、common/lib、common/endorsed
????? catalinaLoader: server/classes、server/lib、commonLoader
????? sharedLoader:? shared/classes、shared/lib、commonLoader
?? 2. 引導(dǎo)Catalina的啟動。
????? 用Reflection技術(shù)調(diào)用org.apache.catalina.startup.Catalina的process方法, 并傳遞參數(shù)過去。
??
2.3 Catalina.java
?? Catalina完成了幾個重要的任務(wù):
?? 1. 使用Digester技術(shù)裝配tomcat各個容器與組件。
????? 1.1?裝配工作的主要內(nèi)容是安裝各個大件。 比如server下有什么樣的servcie。 Host會容納多少個context。 Context都會使用到哪些組件等等。
????? 1.2?同時呢, 在裝配工作這一步, 還完成了mbeans的配置工作。 在這里,我簡單地但不十分精確地描述一下mbean是什么,干什么用的。
????????? 我們自己生成的對象, 自己管理, 天經(jīng)地義! 但是如果我們創(chuàng)建了對象了, 想讓別人來管, 怎么辦呢? 我想至少得告訴別人我們都有什么, 以及通過什么方法可以找到? 吧! JMX技術(shù)給我們提供了一種手段。 JMX里面主要有3種東西。Mbean, agent, connector.
?????? Mbean: 用來映射我們的對象。也許mbean就是我們創(chuàng)建的對象, 也許不是, 但有了它, 就可以引用到我們的對象了。
?????? Agent:? 通過它, 就可以找到mbean了。
?????? Connector: 連接Agent的方式。 可以是http的, 也可以是rmi的,還可以直接通過socket。
????? 發(fā)生在tomcat 裝配過程中的事情:? GlobalResourcesLifecycleListener 類的初始化會被觸發(fā):
???????? protected static Registry registry = MBeanUtils.createRegistry();? 會運行
???????? MBeanUtils.createRegistry()? 會依據(jù)/org/apache/catalina/mbeans/mbeans-descriptors.xml這個配置文件創(chuàng)建 mbeans. Ok, 外界就有了條途徑訪問tomcat中的各個組件了。(有點像后門兒)
?? 2. 為top level 的server 做初始化工作。 實際上就是做通常會配置給service的兩條connector.(http, ajp)
?? 3. 從server這個容器開始啟動, 點燃整個tomcat.
?? 4. 為server做一個hook程序, 檢測當(dāng)server shutdown的時候, 關(guān)閉tomcat的各個容器用。
?? 5. 監(jiān)聽8005端口, 如果發(fā)送"SHUTDOWN"(默認(rèn)培植下字符串)過來, 關(guān)閉8005serverSocket。
2.4 啟動各個容器
?? 1. Server
????? 觸發(fā)Server容器啟動前(before_start), 啟動中(start), 啟動后(after_start)3個事件, 并運行相應(yīng)的事件處理器。
????? 啟動Server的子容器:Servcie.
?? 2. Service
????? 啟動Service的子容器:Engin
????? 啟動Connector
?? 3. Engin
????? 到了Engin這個層次,以及以下級別的容器, Tomcat就使用了比較一致的啟動方式了。
????? 首先,? 運行各個容器自己特有一些任務(wù)
????? 隨后,? 觸發(fā)啟動前事件
????? 立即,? 設(shè)置標(biāo)簽,就表示該容器已經(jīng)啟動
????? 接著,? 啟動容器中的各個組件: loader, logger, manager等等
????? 再接著,啟動mapping組件。(注1)
????? 緊跟著,啟動子容器。
????? 接下來,啟動該容器的管道(pipline)
????? 然后,? 觸發(fā)啟動中事件
????? 最后,? 觸發(fā)啟動后事件。
?
????? Engin大致會這么做, Host大致也會這么做, Context大致還是會這么做。 那么很顯然地, 我們需要在這里使用到代碼復(fù)用的技術(shù)。 tomcat在處理這個問題的時候, 漂亮地使用了抽象類來處理。 ContainerBase. 最后使得這部分完成復(fù)雜功能的代碼顯得干凈利落, 干練爽快, 實在是令人覺得嘆為觀止, 細(xì)細(xì)品來, 直覺如享佳珍, 另人齒頰留香, 留戀往返啊!
?????
????? Engin的觸發(fā)啟動前事件里, 會激活綁定在Engin上的唯一一個Listener:EnginConfig。
????? 這個EnginConfig類基本上沒有做什么事情, 就是把EnginConfig的調(diào)試級別設(shè)置為和Engin相當(dāng)。 另外就是輸出幾行文本, 表示Engin已經(jīng)配置完畢, 并沒有做什么實質(zhì)性的工作。
????? 注1: mapping組件的用處是, 當(dāng)一個需求將要從父容器傳遞到子容器的時候, 而父容器又有多個子容器的話, 那么應(yīng)該選擇哪個子容器來處理需求呢? 這個由mapping 組件來定奪。
???
?? 4. Host
?????? 同Engin一樣, 也是調(diào)用ContainerBase里面的start()方法, 不過之前做了些自個兒的任務(wù),就是往Host這個容器的通道(pipline)里面, 安裝了一個叫做
?“org.apache.catalina.valves.ErrorReportValve”的閥門。
?????? 這個閥門的用處是這樣的:? 需求在被Engin傳遞給Host后, 會繼續(xù)傳遞給Context做具體的處理。 這里需求其實就是作為參數(shù)傳遞的Request, Response。 所以在context把需求處理完后, 通常會改動response。 而這個org.apache.catalina.valves.ErrorReportValve的作用就是檢察response是否包含錯誤, 如果有就做相應(yīng)的處理。
?? 5. Context
?????? 到了這里, 就終于輪到了tomcat啟動中真正的重頭戲,啟動Context了。
?StandardContext.start() 這個啟動Context容器的方法被StandardHost調(diào)用.
?5.1 webappResources 該context所指向的具體目錄
?5.2 安裝defaultContex, DefaultContext 就是默認(rèn)Context。 如果我們在一個Host下面安裝了DefaultContext,而且defaultContext里面又安裝了一個數(shù)據(jù)庫連接池資源的話。 那么其他所有的在該Host下的Context, 都可以直接使用這個數(shù)據(jù)庫連接池, 而不用格外做配置了。
? 5.3 指定Loader. 通常用默認(rèn)的org.apache.catalina.loader.WebappLoader這個類。?? Loader就是用來指定這個context會用到哪些類啊, 哪些jar包啊這些什么的。
?5.4 指定 Manager. 通常使用默認(rèn)的org.apache.catalina.session. StandardManager 。 Manager是用來管理session的。
???? 其實session的管理也很好實現(xiàn)。 以一種簡單的session管理為例。 當(dāng)需求傳遞過來的時候, 在Request對象里面有一個sessionId 屬性。 OK, 得到這個sessionId后, 我們就可以把它作為map的key,而value我們可以放置一個HashMap. HashMap里邊兒, 再放我們想放的東西。
?5.5 postWorkDirectory (). Tomcat下面有一個work目錄。 我們把臨時文件都扔在那兒去。 這個步驟就是在那里創(chuàng)建一個目錄。 一般說來會在%CATALINA_HOME%/work/Standalone\localhost\ 這個地方生成一個目錄。
5.6? Binding thread。到了這里, 就應(yīng)該發(fā)生 class Loader 互換了。 之前是看得見tomcat下面所有的class和lib. 接下來需要看得見當(dāng)前context下的class。 所以要設(shè)置contextClassLoader, 同時還要把舊的ClassLoader記錄下來,因為以后還要用的。
5.7? 啟動 Loader. 指定這個Context具體要使用哪些classes, 用到哪些jar文件。 如果reloadable設(shè)置成了true, 就會啟動一個線程來監(jiān)視classes的變化, 如果有變化就重新啟動Context。
5.8? 啟動logger
5.9? 觸發(fā)安裝在它身上的一個監(jiān)聽器。
?lifecycle.fireLifecycleEvent(START_EVENT, null);
?作為監(jiān)聽器之一,ContextConfig會被啟動. ContextConfig就是用來配置web.xml的。 比如這個Context有多少Servlet, 又有多少Filter, 就是在這里給Context裝上去的。
?5.9.1 defaultConfig. 每個context都得配置 tomcat/conf/web.xml 這個文件。
?5.9.2 applicationConfig 配置自己的 WEB-INF/web.xml 文件
5.9.3 validateSecurityRoles 權(quán)限驗證。 通常我們在訪問/admin 或者/manager的時候,需要用戶要么是admin的要么是manager的, 才能訪問。 而且我們還可以限制那些資源可以訪問, 而哪些不能。 都是在這里實現(xiàn)的。
5.9.4 tldScan: 掃描一下, 需要用到哪些標(biāo)簽(tag lab)
5.10 啟動 manager
5.11 postWelcomeFiles() 我們通常會用到的3個啟動文件的名稱:
index.html、index.htm、index.jsp 就被默認(rèn)地綁在了這個context上
?5.12 listenerStart 配置listener
?5.13 filterStart 配置 filter
?5.14 啟動帶有<load-on-startup>1</load-on-startup>的Servlet.
? 順序是從小到大: 1,2,3… 最后是0
? 默認(rèn)情況下, 至少會啟動如下3個的Servlet:
? org.apache.catalina.servlets.DefaultServlet??
????? 處理靜態(tài)資源的Servlet. 什么圖片啊, html啊, css啊, js啊都找他
? org.apache.catalina.servlets.InvokerServlet
????? 處理沒有做Servlet Mapping的那些Servlet.
? org.apache.jasper.servlet.JspServlet
????? 處理JSP文件的.
?????? 5.15? 標(biāo)識context已經(jīng)啟動完畢。
?走了多少個步驟啊, Context總算是啟動完畢嘍。
??? OK! 走到了這里, 每個容器以及組件都啟動完畢。 Tomcat終于不辭辛勞地為人民服務(wù)了!
3. 參考文獻(xiàn):
??? < http://jakarta.apache.org/tomcat/ >
??? < http://www.onjava.com/pub/a/onjava/2003/05/14/java_webserver.html >
???
4. 后記
??? 這篇文章是講解tomcat啟動框架的,還有篇文章是講解TOMCAT里面的消息處理流程的細(xì)節(jié)的。 文章內(nèi)容已經(jīng)寫好了, 現(xiàn)在正在整理階段。 相信很快就可以做出來, 大家共同研究共同進(jìn)步。
??? 這篇文章是獨自分析TOMCAT源碼所寫的, 所以一定有地方是帶有個人主觀色彩, 難免會有片面之處。若有不當(dāng)之處敬請批評指教,這樣不僅可以使剛開始研究TOMCAT的兄弟們少走彎路, 我也可以學(xué)到東西。
??? email: sojan_java@yahoo.com.cn

5. tomcat源碼分析(消息處理)

TOMCAT源碼分析(啟動框架)


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

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

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

【本文對您有幫助就好】

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

發(fā)表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 人人爱天天做夜夜爽毛片 | 精品亚洲一区二区三区在线播放 | 色 综合 欧美 亚洲 国产 | 真实国产乱子伦精品免费 | 亚洲天堂一区 | 色婷婷久久综合中文网站 | 久久精品动漫99精品动漫 | 亚洲视频一二区 | 久久不射视频 | 中日韩欧美中文字幕毛片 | 国产在视频线在精品 | 性生活一级毛片 | 精品一区二区三区在线视频 | 一级网站在线观看 | 天天摸日日碰天天看免费 | 国产乱人免费视频 | 青青在线成人免费视频 | 免费国产视频 | fxxxx性欧美高清 | 久久精品国产亚洲沈樵 | 曰本一区二区 | 高清国产一区二区三区 | 婷婷国产成人久久精品激情 | 久久久久久久久久久9精品视频 | 亚洲精品一区二区中文 | 国产一区精品视频 | www.免费黄色 | 精品免费久久久久久成人影院 | 日本中文字幕在线观看视频 | 一级黄色免费毛片 | 国产成年 | 我要看一级毛片 | 精品国产免费一区二区 | 亚洲综合日韩在线亚洲欧美专区 | 亚洲高清中文字幕 | 四小虎免费永久观看 | 青青青青爽视频在线播放 | 亚洲视频一区二区在线观看 | 亚洲视频1 | 天天综合久久 | 国产一极毛片 |