天天看點

還是源碼來的直接---讀mina源碼

轉載請注明出處http://chillwarmoon.iteye.com

多好的文檔也不如源碼來的直接。如果自己的程式對于某種技術過于依賴,有時候僅看那麼幾頁的文檔,總是感覺放心不下。還是看看源碼,多多了解内部的實作機制為好。

一 讀源碼時,首先要弄清楚代碼所涉及到的重要模型及其之間的關系,從整體架構方面了解其組成。

1.對于IOService的實作NioSocketConnector和NioSocketAcceptor來說,都持有selector的引用,本身都有一個固定的線程池executor,用來執行Connector或者Acceptor任務。

2.除此之外,IoService還有對Processor池的引用,該池中的元素processor的數量是機器的cpu核數+1。

3.processor池中預設元素為NioProcessor對象,每個元素都有一個selector,而且有一個executor線程池,用來執行Processor任務。

二 分析架構的初始化方式,注意不要陷入技術細節,仍然是整體把握。

4.IoService初始化時,需要通過具體的實作提供的transportMetaData,來判斷其中規定的session配置類(例如:DefaultSocketSessionConfig)是否來自接口SessionConfig。

5.IoService初始化時,建立與監聽器容器IoServiceListenerSupport的雙向關聯,注冊匿名内部實作serviceActivationListener到監聽器容器。

PS:Mina架構比起Tomcat源碼來說簡單很多,Tomcat啟動邏輯就花了很長時間來讀。

三 要充分利用eclipse中提供給我們查找源碼的方法,例如Ctrl+T,Ctrl+H,Ctrl+.,Alt+Shift+o等等。

四 架構初始化後,根據架構的使用方式,來逐漸分析代碼。

6.關鍵是對Session的了解:

持有對IoService,Processor池,SocketChannel,SessionConfig和IoService.IoHandler的引用。

在初始化session時,将config配置到了SocketChannel中。

深入了解:

在每次connect後,都會建立與之對應的session(session與channel是1:1關系),而且每個session都加入了processor中,但是都是持有的對一個IoHandler的引用。

将session加入到processor池:

該processor元素的選取是依次在池中選擇的。然後将該processor元素加入到了session的attribute中。

也就是說,不同的session可能加入到池中的一個processor元素,一個processor元素有一個selector和一個Processor線程,該線程可以對processor元素對應的這些session進行處理。

7.Processor線程:

(1)如果有newSession,則将channel注冊事件SelectionKey.OP_READ到該processor元素的selector

(2)将getFilterChainBuilder中的鍊節點加入到該session的鍊中

(3)fire相應的SessionCreate和SessionOpen的chain節點

(4)如果SelectionKey.OP_READ準備好,則read資料,如果session對應的發送隊列有資料,則write資料

如果建立的session都放在了一個processor元素裡,則handler隻能夠被一個線程通路,否則handler可能會被多個線程執行。

繼續閱讀