Container提供管理bean的能力。html
基於Jetty-9.4.8.v20171121。java
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的增長和刪除事件。ide
從類圖能夠看出,Container與LifeCycle接口很相似,都是不少組件的基本特徵,其默認實現是ContainerLifeCycle。源碼分析
1.2類圖能夠看出ContainerLifeCycle不只是Container的默認實現,並且也是不少組件(Connector,Handler等)默認實現的父類。this
ContainerLifeCycle天然要實現Container接口; debug
ContainerLifeCycle繼承AbstractLifeCycle,而AbstractLifeCycle裏面實現了LifeCycle的模板啓停方法start和stop;rest
繼承AbstractLifeCycle的子類只須要實現AbstractLifeCycle中增長的doStart和doStop實現子類具體的啓動和中止,具體請參考【Jetty - LifeCycle源碼分析】htm
ContainerLifeCycle.Bean:內部類,表示管理的Bean對象。對象
ContainerLifeCycle.Managed:內部類,被管理的Bean有幾種類型:POJO,MANAGED,UNMANAGED,AUTO。blog
啓動主要分爲以下兩個步驟:
(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); } } }
// o:bean,managed:bean類型 // 注意基本原則:在ContainerLifeCycle類裏面有兩個字段_beans和_listener,若是添加的bean也是Container.Listener類型,則須要在_listener裏面也增長一個 public boolean addBean(Object o, Managed managed) { if (o==null || contains(o)) // 若是bean爲null或者已經存在 return false; Bean new_bean = new Bean(o); // 包裝爲Bean對象 // 若是bean是Container.Listener if (o instanceof Container.Listener) addEventListener((Container.Listener)o); // 添加bean _beans.add(new_bean); // 通知全部_listeners,有新bean添加的事件 for (Container.Listener l:_listeners) l.beanAdded(this,o); try { switch (managed) { case UNMANAGED: unmanage(new_bean); break; case MANAGED: manage(new_bean); // 若是ContainerLifeCycle在啓動中,即調用doStart尚未退出 if (isStarting() && _doStarted) { // 此處o是一個任意類型且是個public方法,此處直接轉爲LifeCycle是否有問題? LifeCycle l = (LifeCycle)o; // 爲何有這樣的判斷? // doStart的過程(1)設置狀態位(2)以bean添加的順序啓動具備生命週期的bean,若是此時調用了addBean有可能同步的問題,致使新添加的bean沒有經過doStart啓動,因此須要在此處判斷若是未啓動,則啓動一下 if (!l.isRunning()) start(l); } break; case AUTO: if (o instanceof LifeCycle) { LifeCycle l = (LifeCycle)o; if (isStarting()) // 若是ContainerLifeCycle啓動中 { if (l.isRunning()) // 若是bean運行中,則設置爲未託管,不須要ContainerLifeCycle管理啓動 unmanage(new_bean); else if (_doStarted) // 若是bean未運行,而且ContainerLifeCyle啓動中,則設置爲託管bean而且啓動之 { manage(new_bean); start(l); } else new_bean._managed=Managed.AUTO; } else if (isStarted()) // 若是ContainerLifeCycle已經啓動 unmanage(new_bean); else // ContainerLifeCycle未啓動 new_bean._managed=Managed.AUTO; } else new_bean._managed=Managed.POJO; break; case POJO: new_bean._managed=Managed.POJO; } } catch (RuntimeException | Error e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } if (LOG.isDebugEnabled()) LOG.debug("{} added {}",this,new_bean); return true; }
// 刪除bean private boolean remove(Bean bean) { if (_beans.remove(bean)) { boolean wasManaged = bean.isManaged(); // bean是不是託管類型 unmanage(bean); // 設置bean爲未託管類型 for (Container.Listener l:_listeners) // 通知監聽器 l.beanRemoved(this,bean._bean); // 若是被remove的bean是Listener,須要調用removeEventListener if (bean._bean instanceof Container.Listener) removeEventListener((Container.Listener)bean._bean); // 若是是具備生命週期託管的bean須要中止。 if (wasManaged && bean._bean instanceof LifeCycle) { try { stop((LifeCycle)bean._bean); } catch(RuntimeException | Error e) { throw e; } catch (Exception e) { throw new RuntimeException(e); } } return true; } return false; }
經過前面的doStart和addBean能夠基本肯定Container管理bean的以下幾條規則:
ContainerLifeCycle是對容器化bean組件的一個生命週期的實現。
bean能夠做爲託管bean或未託管bean放入ContainerLifeCycle裏面。
託管bean的啓動中止和銷燬由ContainerLifeCycle控制;未託管主要是爲了dump,它們的生命週期必須獨立管理。
當一個沒有指定類型具備生命週期的bean加入到ContainerLifeCycle,ContianerLifeCycle能夠推斷它的類型:
(1)若是增長的bean運行中,它將以未託管類型加入container;
(2)若是增長的bean未運行且container也未運行,它將以AUTO類型加入container;
(3)若是增長的bean未運行且container在啓動中,它將以託管類型加入container;
(4)若是增長的bean未運行且container已經啓動,它將以未託管類型加入container;
當container已經啓動,全部的託管bean也應該啓動。
任何AUTO類型的bean都將依據它們的狀態被分爲託管或未託管,若是已經啓動則爲未託管,不然將啓動它們而後設置爲託管類型。
Contianer啓動以後添加的bean將不會被啓動,它們的狀態須要顯式管理。
當中止Container的時候,只有被這個Container啓動的bean纔會中止。
若是一個bean被多個Container共享,那麼該bean只能是未託管的,即在增長以前,應該被啓動
manage是設置bean爲託管類型,unmanage設置bean爲未託管類型。
能夠理解爲兩個相反的操做,須要注意若是被設置的bean是個Container,則須要將當前_listeners裏面全部類型爲InheritedListener的監聽器添加到該bean裏面或從該bean裏面移除。
// 託管bean private void manage(Bean bean) { if (bean._managed!=Managed.MANAGED) { bean._managed=Managed.MANAGED; // 設置bean爲託管 if (bean._bean instanceof Container) { for (Container.Listener l:_listeners) { if (l instanceof InheritedListener) // 若是當前bean的listener裏面有是InheritedListener須要增長到bean的_beans列表中 { if (bean._bean instanceof ContainerLifeCycle) ((ContainerLifeCycle)bean._bean).addBean(l,false); else ((Container)bean._bean).addBean(l); } } } if (bean._bean instanceof AbstractLifeCycle) { ((AbstractLifeCycle)bean._bean).setStopTimeout(getStopTimeout()); } } }
// 未託管bean private void unmanage(Bean bean) { if (bean._managed!=Managed.UNMANAGED) { if (bean._managed==Managed.MANAGED && bean._bean instanceof Container) { for (Container.Listener l:_listeners) { // 若是監聽器是InheritedListener,須要將其從未託管的bean中移除 if (l instanceof InheritedListener) ((Container)bean._bean).removeBean(l); } } bean._managed=Managed.UNMANAGED; } }
兩個是相反的操做,一個是增長Listener,另外一個是刪除Listener。
若是待操做的Listener是InheritedListener子類,須要級聯操做。
@Override public void addEventListener(Container.Listener listener) { if (_listeners.contains(listener)) return; _listeners.add(listener); // 新加的Listener須要被告知全部bean for (Bean b:_beans) { listener.beanAdded(this,b._bean); // 若是是InheritedListener須要增長到bean爲Container的_beans列表中 if (listener instanceof InheritedListener && b.isManaged() && b._bean instanceof Container) { if (b._bean instanceof ContainerLifeCycle) ((ContainerLifeCycle)b._bean).addBean(listener, false); else ((Container)b._bean).addBean(listener); } } }
@Override public void removeEventListener(Container.Listener listener) { if (_listeners.remove(listener)) { // remove existing beans for (Bean b:_beans) { listener.beanRemoved(this,b._bean); // 與增長相反,須要級聯移除 if (listener instanceof InheritedListener && b.isManaged() && b._bean instanceof Container) ((Container)b._bean).removeBean(listener); } } }
最後ContainerLifeCycle還提供了重載的updateBean,入參通常是一個老bean和一個新bean。
通常操做都是先刪除老bean,而後增長新bean,都是複用上面提到的removeBean和addBean,不在詳細描述。