Tomcat源碼淺析


最近在學習tomcat源碼,算是把tomcat的整個流程梳理通了。

 

 

從上圖來看,tomcat把模塊化使用到了極致,配合組件生命周期的管理,讓代碼看起來結構清晰,而且很容易進行業務擴展。

1.上圖的接口Sever,Service,Connector,Container…..都是一個組件接口,這些組件的關系是,Server包含一個或多個Service,一個Service包含多個Container和與這個Container相關聯的Connector,然后Container根據自身需要關聯下面的Jasper,Naming…..等組件。Tomcat提供一鍵式啟動和關閉服務,就是以剛剛所說的組件之間的關系來執行的,在啟動一個組件的時候,會啟動與其相關聯的組件,這樣會啟動所有的組件,而客戶端不需要關心其余組件的啟動細節。

拿StandardServer的啟動來舉例:

protected void startInternal() throws LifecycleException {
    fireLifecycleEvent(CONFIGURE_START_EVENT, null);

//這個方法負責啟動前的准備工作,用觀察者模式實現
    setState(LifecycleState.STARTING);
//標記組件的狀態
    globalNamingResources.start();
//相關聯組件的啟動
    synchronized (servicesLock) {
        for (int i = 0; i < services.length; i++) {
            services[i].start();
        }
    }
}

說明一下,組件的啟動和關閉時,調用組件的start和stop方法,這兩個是模板方法,模板方法中調用的startInternal方法由子類來實現。可以看到Sever會啟動globalNamingResource組件和關聯的Service組件,實現一鍵式功能。

2. startInternal方法的第一行

fireLifecycleEvent(CONFIGURE_START_EVENT, null);

是為了做一些Sever啟動前的准備工作,使用的是觀察者模式來實現的。

Tomcat的觀察者模式主要接口有:Lifecycle,LifecycleEvent,LifecycleListener,LifecycleSupport。

其中LifecycleListener是觀察者,負責等待通知然后進行一些與發送的事件想匹配的操作,具體實現類有ContextConfig, HostConfig, EngineConfig,LifecycleEvent 是發送的事件,Lifecycle是被觀察者(主題),具體的實現類有StandardServer,StandardContext等等組件,組件啟動的時候,會將啟動的動作封裝成一個事件,然后調用觀察者的回調方法,來進行相關操作,LifecycleSupport是一個生命周期的管理類,組件的觀察者的管理委托LifecycleSupport來實現,因此所有的組件中都有一個LifecycleSupport的引用,在容器類的抽象類ContainerBase中代碼如下:

protected LifecycleSupport lifecycle = new LifecycleSupport(this);

 

    public void addLifecycleListener(LifecycleListener listener) {

 

        lifecycle.addLifecycleListener(listener);

 

    }

 

    public LifecycleListener[] findLifecycleListeners() {

 

        return lifecycle.findLifecycleListeners();

 

    public void removeLifecycleListener(LifecycleListener listener) {

 

        lifecycle.removeLifecycleListener(listener);

 

}

 

對觀察者的管理以及動作的觸發,都委托LifecycleSupport來實現。

這里主要做三件事:調用組件的啟動方法,啟動組件;調用子容器的啟動方法,啟動子容器;通知容器的觀察者,使其執行相應的啟動動作。每一層次的容器都這樣啟動,最終整個Tomcat啟動完畢。

3. Tomcat中有四種不同的容器:

Engine:代表整個Catalina servle引擎

Host:代表虛擬主機

Context:代表某個web應用

Wrapper:代表某個應用中的servlet

這些容器都是父子的關系,Engine位於最頂層,一個Engine包含多個Host,一個Host(虛擬主機)包含多個Context(web應用),一個Context(web 應用)包含多個Wrapper(servlet),Wrapper位於最底層,沒有孩子。當父容器啟動時,相應的子容器也應該啟動,子容器的子容器也啟動。

4.好了,先說到這兒,還有一部分容器管道沒有說,下次再介紹一下tomcat如何用管道閥來簡化開發流程和增強程序擴展性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM