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)刪除beanpublic boolean addBean(Object o);// 返回該Container里面所有的beanpublic Collection<Object> getBeans();// 返回指定類型(包括子類)的beanpublic <T> Collection<T> getBeans(Class<T> clazz);// 返回指定類型(包括子類)的第一個bean,如果不存在則返回nullpublic <T> T getBean(Class<T> clazz);// 刪除指定的bean,如果bean是一個Container.Listener,隱含調用removeEventListener(Container.Listener)public boolean removeBean(Object o);// 增加一個Listenerpublic void addEventListener(Listener listener);// 刪除一個Listenerpublic void removeEventListener(Listener listener);// 未托管一個bean(必須已經存在在Container里面),所以該bean不應該啟動,停止或銷毀void unmanage(Object bean);// 托管一個bean(必須已經存在在Container里面),所以該bean已啟動,已停止或銷毀void manage(Object bean);// 檢測該Container是否托管一個beanboolean 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@Overrideprotected void doStart() throws Exception{if (_destroyed)throw new IllegalStateException("Destroyed container cannot be restarted");// 標示已經啟動,addBean可以啟動其他的bean_doStarted = true;// 啟動托管和自動beansfor (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: // 如果是自動beanif (l.isRunning()) // 如果已經運行了,則設置為未托管unmanage(b);else // 如果未運行,設置為托管,并且啟動{manage(b); start(l);}break;}}}// 此處調用父類的doStart方法,就是AbstractLifeCycle的doStart方法,其實是個空實現super.doStart();}
停止主要分為兩個步驟:
(1)設置標志位;
(2)逆序停止具有生命周期的托管bean,為什么逆序?主要與啟動順序比較,防止bean之間有關聯出現錯誤,類似資源釋放。
// 以添加的逆序停止具有生命周期的托管bean@Overrideprotected void doStop() throws Exception{ _doStarted = false; // 設置停止狀態位super.doStop(); // 調用AbstractLifeCycle的doStop方法,其實是個空方法List<Bean> reverse = new ArrayList<>(_beans);Collections.reverse(reverse); // 逆序for (Bean b : reverse) { // 具有生命周期并且托管的beanif (b._managed==Managed.MANAGED && b._bean instanceof LifeCycle){LifeCycle l = (LifeCycle)b._bean;stop(l);}}}
2.3 addBean
// 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.Listenerif (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);}elsenew_bean._managed=Managed.AUTO; }else if (isStarted()) // 如果ContainerLifeCycle已經啟動unmanage(new_bean);else // ContainerLifeCycle未啟動new_bean._managed=Managed.AUTO;}elsenew_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,需要調用removeEventListenerif (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;}
?
2.4 插播Container管理bean的規則
通過前面的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只能是未托管的,即在增加之前,應該被啟動
2.4.1 實例
?
2.5 manage和unmanage
?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;}}
2.6 addEventListener和removeEventListener
兩個是相反的操作,一個是增加Listener,另一個是刪除Listener。
如果待操作的Listener是InheritedListener子類,需要級聯操作。
@Overridepublic void addEventListener(Container.Listener listener){if (_listeners.contains(listener))return;_listeners.add(listener);// 新加的Listener需要被告知所有beanfor (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);}}}
?
@Overridepublic void removeEventListener(Container.Listener listener){if (_listeners.remove(listener)){// remove existing beansfor (Bean b:_beans){listener.beanRemoved(this,b._bean);// 與增加相反,需要級聯移除if (listener instanceof InheritedListener && b.isManaged() && b._bean instanceof Container)((Container)b._bean).removeBean(listener);}}}
2.7 updateBean
最后ContainerLifeCycle還提供了重載的updateBean,入參一般是一個老bean和一個新bean。
一般操作都是先刪除老bean,然后增加新bean,都是復用上面提到的removeBean和addBean,不在詳細描述。?