Jetty - Container源碼分析
1. 描述
Container提供管理bean的能力。
基於Jetty-9.4.8.v20171121。
1.1 API
public interface Container { // 增加一個bean,如果bean是一個Container.Listener則隱含調用addEventListener(Container.Listener)方法 // Container.Listener只關心兩個事件:(1)增加bean(2)刪除bean public boolean addBean(Object o); // 返回該Container裏面所有的bean public Collection<Object> getBeans(); // 返回指定類型(包括子類)的bean public <T> Collection<T> getBeans(Class<T> clazz); // 返回指定類型(包括子類)的第一個bean,如果不存在則返回null public <T> T getBean(Class<T> clazz); // 刪除指定的bean,如果bean是一個Container.Listener,隱含調用removeEventListener(Container.Listener) public boolean removeBean(Object o); // 增加一個Listener public void addEventListener(Listener listener); // 刪除一個Listener public void removeEventListener(Listener listener); // 未托管一個bean(必須已經存在在Container裏面),所以該bean不應該啟動,停止或銷毀 void unmanage(Object bean); // 托管一個bean(必須已經存在在Container裏面),所以該bean已啟動,已停止或銷毀 void manage(Object bean); // 檢測該Container是否托管一個bean boolean isManaged(Object bean); // 增加一個bean,並且明確是否托管(即是否管理該bean的生命周期) // 如果已經增加返回true,如果已經存在返回false boolean addBean(Object o, boolean managed); // Container事件的監聽器 // 如果一個增加的bean實現該接口將會收到該Container的事件 public interface Listener { void beanAdded(Container parent,Object child); void beanRemoved(Container parent,Object child); } /** * Inherited Listener. * If an added bean implements this interface, then it will * be added to all contained beans that are themselves Containers* 如果增加的bean實現該接口,則將該bean增加到當前Container裏面所有bean類型為Container裏面。 */ public interface InheritedListener extends Listener { } /** * @param clazz the class of the beans * @return the list of beans of the given class from the entire managed hierarchy * @param <T> the Bean type */ public <T> Collection<T> getContainedBeans(Class<T> clazz); }
從API可以看出Container主要維護bean並且監聽bean的增加和刪除事件。
1.2 類圖
從類圖可以看出,Container與LifeCycle接口很類似,都是很多組件的基本特征,其默認實現是ContainerLifeCycle。
2. ContainerLifeCycle
1.2類圖可以看出ContainerLifeCycle不僅是Container的默認實現,而且也是很多組件(Connector,Handler等)默認實現的父類。
2.1 類圖
ContainerLifeCycle自然要實現Container接口;
ContainerLifeCycle繼承AbstractLifeCycle,而AbstractLifeCycle裏面實現了LifeCycle的模板啟停方法start和stop;
繼承AbstractLifeCycle的子類只需要實現AbstractLifeCycle中增加的doStart和doStop實現子類具體的啟動和停止,具體請參考【Jetty - LifeCycle源碼分析】
ContainerLifeCycle.Bean:內部類,表示管理的Bean對象。
ContainerLifeCycle.Managed:內部類,被管理的Bean有幾種類型:POJO,MANAGED,UNMANAGED,AUTO。
2.2 doStart和doStop
啟動主要分為如下兩個步驟:
(1)設置標誌位_doStart = true;
(2)啟動具有生命周期的bean(a)如果托管bean並且未運行的,則啟動(b)如果是自動bean並且運行中,則設置為未托管;未運行的,則設置為托管,並且啟動;
// 以添加的順序啟動托管的bean @Override protected void doStart() throws Exception { if (_destroyed) throw new IllegalStateException("Destroyed container cannot be restarted"); // 標示已經啟動,addBean可以啟動其他的bean _doStarted = true; // 啟動托管和自動beans for (Bean b : _beans) // 遍歷所有bean { if (b._bean instanceof LifeCycle) { LifeCycle l = (LifeCycle)b._bean; switch(b._managed) { case MANAGED: // 如果是托管bean,並且未運行,則啟動 if (!l.isRunning()) start(l); break; case AUTO: // 如果是自動bean if (l.isRunning()) // 如果已經運行了,則設置為未托管 unmanage(b); else // 如果未運行,設置為托管,並且啟動 { manage(b); start(l); } break; } } } // 此處調用父類的doStart方法,就是AbstractLifeCycle的doStart方法,其實是個空實現 super.doStart(); }
停止主要分為兩個步驟:
(1)設置標誌位;
(2)逆序停止具有生命周期的托管bean,為什麽逆序?主要與啟動順序比較,防止bean之間有關聯出現錯誤,類似資源釋放。
// 以添加的逆序停止具有生命周期的托管bean @Override protected void doStop() throws Exception { _doStarted = false; // 設置停止狀態位 super.doStop(); // 調用AbstractLifeCycle的doStop方法,其實是個空方法 List<Bean> reverse = new ArrayList<>(_beans); Collections.reverse(reverse); // 逆序 for (Bean b : reverse) { // 具有生命周期並且托管的bean if (b._managed==Managed.MANAGED && b._bean instanceof LifeCycle) { LifeCycle l = (LifeCycle)b._bean; stop(l); } } }
2.3 addBean
Jetty - Container源碼分析