<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                ### Lifecycle生命周期 前面我們看到`Container`容器 繼承了`Lifecycle`生命周期。如果想讓一個系統能夠對外提供服務,我們需要創建、組裝并啟動這些組件;在服務停止的時候,我們還需要釋放資源,銷毀這些組件,因此這是一個動態的過程。也就是說,Tomcat 需要動態地管理這些組件的生命周期。 如何統一管理組件的創建、初始化、啟動、停止和銷毀?如何做到代碼邏輯清晰?如何方便地添加或者刪除組件?如何做到組件啟動和停止不遺漏、不重復? ##### 一鍵式啟停:LifeCycle 接口 設計就是要找到系統的變化點和不變點。這里的不變點就是每個組件都要經歷創建、初始化、啟動這幾個過程,這些狀態以及狀態的轉化是不變的。而變化點是每個具體組件的初始化方法,也就是啟動方法是不一樣的。 因此,Tomcat 把不變點抽象出來成為一個接口,這個接口跟生命周期有關,叫作 LifeCycle。LifeCycle 接口里定義這么幾個方法:`init()、start()、stop() 和 destroy()`,每個具體的組件(也就是容器)去實現這些方法。 在父組件的`init()`方法里需要創建子組件并調用子組件的`init()`方法。同樣,在父組件的`start()`方法里也需要調用子組件的`start()`方法,因此調用者可以無差別的調用各組件的`init()`方法和`start()`方法,這就是**組合模式**的使用,并且只要調用最頂層組件,也就是 Server 組件的`init()`和`start()`方法,整個 Tomcat 就被啟動起來了。所以 Tomcat 采取組合模式管理容器,容器繼承 LifeCycle 接口,這樣就可以向針對單個對象一樣一鍵管理各個容器的生命周期,整個 Tomcat 就啟動起來。 ##### 可擴展性:LifeCycle 事件 我們再來考慮另一個問題,那就是系統的可擴展性。因為各個組件`init()`和`start()`方法的具體實現是復雜多變的,比如在 Host 容器的啟動方法里需要掃描 webapps 目錄下的 Web 應用,創建相應的 Context 容器,如果將來需要增加新的邏輯,直接修改`start()`方法?這樣會違反開閉原則,那如何解決這個問題呢?開閉原則說的是為了擴展系統的功能,你不能直接修改系統中已有的類,但是你可以定義新的類。 **組件的`init()`和`start()`調用是由它的父組件的狀態變化觸發的,上層組件的初始化會觸發子組件的初始化,上層組件的啟動會觸發子組件的啟動,因此我們把組件的生命周期定義成一個個狀態,把狀態的轉變看作是一個事件。而事件是有監聽器的,在監聽器里可以實現一些邏輯,并且監聽器也可以方便的添加和刪除**,這就是典型的**觀察者模式**。 以下就是`Lyfecycle`接口的定義: ![](https://img.kancloud.cn/ca/58/ca584b5a8df24e41c194d11fd24bd364_347x291.png) ##### 重用性:LifeCycleBase 抽象基類 再次看到抽象模板設計模式。 有了接口,我們就要用類去實現接口。一般來說實現類不止一個,不同的類在實現接口時往往會有一些相同的邏輯,如果讓各個子類都去實現一遍,就會有重復代碼。那子類如何重用這部分邏輯呢?其實就是定義一個基類來實現共同的邏輯,然后讓各個子類去繼承它,就達到了重用的目的。 Tomcat 定義一個基類 LifeCycleBase 來實現 LifeCycle 接口,把一些公共的邏輯放到基類中去,比如生命狀態的轉變與維護、生命事件的觸發以及監聽器的添加和刪除等,而子類就負責實現自己的初始化、啟動和停止等方法。 ``` public abstract class LifecycleBase implements Lifecycle{ // 持有所有的觀察者 private final List<LifecycleListener> lifecycleListeners = new CopyOnWriteArrayList<>(); /** * 發布事件 * * @param type Event type * @param data Data associated with event. */ protected void fireLifecycleEvent(String type, Object data) { LifecycleEvent event = new LifecycleEvent(this, type, data); for (LifecycleListener listener : lifecycleListeners) { listener.lifecycleEvent(event); } } // 模板方法定義整個啟動流程,啟動所有容器 @Override public final synchronized void init() throws LifecycleException { //1. 狀態檢查 if (!state.equals(LifecycleState.NEW)) { invalidTransition(Lifecycle.BEFORE_INIT_EVENT); } try { //2. 觸發 INITIALIZING 事件的監聽器 setStateInternal(LifecycleState.INITIALIZING, null, false); // 3. 調用具體子類的初始化方法 initInternal(); // 4. 觸發 INITIALIZED 事件的監聽器 setStateInternal(LifecycleState.INITIALIZED, null, false); } catch (Throwable t) { ExceptionUtils.handleThrowable(t); setStateInternal(LifecycleState.FAILED, null, false); throw new LifecycleException( sm.getString("lifecycleBase.initFail",toString()), t); } } } ``` Tomcat 為了實現一鍵式啟停以及優雅的生命周期管理,并考慮到了可擴展性和可重用性,將面向對象思想和設計模式發揮到了極致,`Containaer`接口維護了容器的父子關系,`Lifecycle`組合模式實現組件的生命周期維護,生命周期每個組件有變與不變的點,運用模板方法模式。 分別運用了**組合模式、觀察者模式、骨架抽象類和模板方法**。 如果你需要維護一堆具有父子關系的實體,可以考慮使用組合模式。 觀察者模式聽起來 “高大上”,其實就是當一個事件發生后,需要執行一連串更新操作。實現了低耦合、非侵入式的通知與更新機制 ![](https://img.kancloud.cn/2c/16/2c169a2f1103d1a5f1d712934d24f0eb_958x681.png) `Container`繼承了 LifeCycle,StandardEngine、StandardHost、StandardContext 和 StandardWrapper 是相應容器組件的具體實現類,因為它們都是容器,所以繼承了 ContainerBase 抽象基類,而 ContainerBase 實現了 Container 接口,也繼承了 LifeCycleBase 類,它們的生命周期管理接口和功能接口是分開的,這也符合設計中**接口分離的原則**
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看