Jetty - Container源码分析
1. 描述
Container提供管理bean的能力。
基于Jetty-9.4.8.v20171121。
1.1 API
public interface Container {// 增加一個bean,如果bean是一個Container.Listener則隱含調(diào)用addEventListener(Container.Listener)方法// Container.Listener只關(guān)心兩個事件:(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,隱含調(diào)用removeEventListener(Container.Listener)public boolean removeBean(Object o);// 增加一個Listenerpublic void addEventListener(Listener listener);// 刪除一個Listenerpublic void removeEventListener(Listener listener);// 未托管一個bean(必須已經(jīng)存在在Container里面),所以該bean不應(yīng)該啟動,停止或銷毀void unmanage(Object bean);// 托管一個bean(必須已經(jīng)存在在Container里面),所以該bean已啟動,已停止或銷毀void manage(Object bean);// 檢測該Container是否托管一個beanboolean isManaged(Object bean);// 增加一個bean,并且明確是否托管(即是否管理該bean的生命周期)// 如果已經(jīng)增加返回true,如果已經(jīng)存在返回false boolean addBean(Object o, boolean managed);// Container事件的監(jiān)聽器// 如果一個增加的bean實現(xiàn)該接口將會收到該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實現(xiàn)該接口,則將該bean增加到當(dāng)前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主要維護(hù)bean并且監(jiān)聽bean的增加和刪除事件。
?
1.2 類圖
從類圖可以看出,Container與LifeCycle接口很類似,都是很多組件的基本特征,其默認(rèn)實現(xiàn)是ContainerLifeCycle。
2. ContainerLifeCycle
1.2類圖可以看出ContainerLifeCycle不僅是Container的默認(rèn)實現(xiàn),而且也是很多組件(Connector,Handler等)默認(rèn)實現(xiàn)的父類。
2.1 類圖
?
ContainerLifeCycle自然要實現(xiàn)Container接口;?
ContainerLifeCycle繼承AbstractLifeCycle,而AbstractLifeCycle里面實現(xiàn)了LifeCycle的模板啟停方法start和stop;
繼承AbstractLifeCycle的子類只需要實現(xiàn)AbstractLifeCycle中增加的doStart和doStop實現(xiàn)子類具體的啟動和停止,具體請參考【Jetty - LifeCycle源碼分析】
ContainerLifeCycle.Bean:內(nèi)部類,表示管理的Bean對象。
ContainerLifeCycle.Managed:內(nèi)部類,被管理的Bean有幾種類型:POJO,MANAGED,UNMANAGED,AUTO。
2.2 doStart和doStop
??啟動主要分為如下兩個步驟:
?(1)設(shè)置標(biāo)志位_doStart = true;
?(2)啟動具有生命周期的bean(a)如果托管bean并且未運行的,則啟動(b)如果是自動bean并且運行中,則設(shè)置為未托管;未運行的,則設(shè)置為托管,并且啟動;?
// 以添加的順序啟動托管的bean@Overrideprotected void doStart() throws Exception{if (_destroyed)throw new IllegalStateException("Destroyed container cannot be restarted");// 標(biāo)示已經(jīng)啟動,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()) // 如果已經(jīng)運行了,則設(shè)置為未托管unmanage(b);else // 如果未運行,設(shè)置為托管,并且啟動{manage(b); start(l);}break;}}}// 此處調(diào)用父類的doStart方法,就是AbstractLifeCycle的doStart方法,其實是個空實現(xiàn)super.doStart();}停止主要分為兩個步驟:
(1)設(shè)置標(biāo)志位;
(2)逆序停止具有生命周期的托管bean,為什么逆序?主要與啟動順序比較,防止bean之間有關(guān)聯(lián)出現(xiàn)錯誤,類似資源釋放。
// 以添加的逆序停止具有生命周期的托管bean@Overrideprotected void doStop() throws Exception{ _doStarted = false; // 設(shè)置停止?fàn)顟B(tài)位super.doStop(); // 調(diào)用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或者已經(jīng)存在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在啟動中,即調(diào)用doStart還沒有退出if (isStarting() && _doStarted) { // 此處o是一個任意類型且是個public方法,此處直接轉(zhuǎn)為LifeCycle是否有問題?LifeCycle l = (LifeCycle)o;// 為什么有這樣的判斷?// doStart的過程(1)設(shè)置狀態(tài)位(2)以bean添加的順序啟動具有生命周期的bean,如果此時調(diào)用了addBean有可能同步的問題,導(dǎo)致新添加的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運行中,則設(shè)置為未托管,不需要ContainerLifeCycle管理啟動unmanage(new_bean);else if (_doStarted) // 如果bean未運行,并且ContainerLifeCyle啟動中,則設(shè)置為托管bean并且啟動之{manage(new_bean);start(l);}elsenew_bean._managed=Managed.AUTO; }else if (isStarted()) // 如果ContainerLifeCycle已經(jīng)啟動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); // 設(shè)置bean為未托管類型for (Container.Listener l:_listeners) // 通知監(jiān)聽器l.beanRemoved(this,bean._bean);// 如果被remove的bean是Listener,需要調(diào)用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的規(guī)則
通過前面的doStart和addBean可以基本確定Container管理bean的如下幾條規(guī)則:
ContainerLifeCycle是對容器化bean組件的一個生命周期的實現(xiàn)。
bean可以作為托管bean或未托管bean放入ContainerLifeCycle里面。
托管bean的啟動停止和銷毀由ContainerLifeCycle控制;未托管主要是為了dump,它們的生命周期必須獨立管理。
當(dāng)一個沒有指定類型具有生命周期的bean加入到ContainerLifeCycle,ContianerLifeCycle可以推斷它的類型:
(1)如果增加的bean運行中,它將以未托管類型加入container;
(2)如果增加的bean未運行且container也未運行,它將以AUTO類型加入container;
(3)如果增加的bean未運行且container在啟動中,它將以托管類型加入container;
(4)如果增加的bean未運行且container已經(jīng)啟動,它將以未托管類型加入container;
當(dāng)container已經(jīng)啟動,所有的托管bean也應(yīng)該啟動。
任何AUTO類型的bean都將依據(jù)它們的狀態(tài)被分為托管或未托管,如果已經(jīng)啟動則為未托管,否則將啟動它們?nèi)缓笤O(shè)置為托管類型。
Contianer啟動之后添加的bean將不會被啟動,它們的狀態(tài)需要顯式管理。
當(dāng)停止Container的時候,只有被這個Container啟動的bean才會停止。
如果一個bean被多個Container共享,那么該bean只能是未托管的,即在增加之前,應(yīng)該被啟動
2.4.1 實例
?
2.5 manage和unmanage
?manage是設(shè)置bean為托管類型,unmanage設(shè)置bean為未托管類型。
可以理解為兩個相反的操作,需要注意如果被設(shè)置的bean是個Container,則需要將當(dāng)前_listeners里面所有類型為InheritedListener的監(jiān)聽器添加到該bean里面或從該bean里面移除。
// 托管bean private void manage(Bean bean){if (bean._managed!=Managed.MANAGED){bean._managed=Managed.MANAGED; // 設(shè)置bean為托管if (bean._bean instanceof Container){for (Container.Listener l:_listeners){if (l instanceof InheritedListener) // 如果當(dāng)前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){ // 如果監(jiān)聽器是InheritedListener,需要將其從未托管的bean中移除if (l instanceof InheritedListener)((Container)bean._bean).removeBean(l);}}bean._managed=Managed.UNMANAGED;}}
2.6 addEventListener和removeEventListener
兩個是相反的操作,一個是增加Listener,另一個是刪除Listener。
如果待操作的Listener是InheritedListener子類,需要級聯(lián)操作。
@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);// 與增加相反,需要級聯(lián)移除if (listener instanceof InheritedListener && b.isManaged() && b._bean instanceof Container)((Container)b._bean).removeBean(listener);}}}2.7 updateBean
最后ContainerLifeCycle還提供了重載的updateBean,入?yún)⒁话闶且粋€老bean和一個新bean。
一般操作都是先刪除老bean,然后增加新bean,都是復(fù)用上面提到的removeBean和addBean,不在詳細(xì)描述。?
轉(zhuǎn)載于:https://www.cnblogs.com/lujiango/p/8361415.html
總結(jié)
以上是生活随笔為你收集整理的Jetty - Container源码分析的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: JsRender 前端渲染模板常用API
 - 下一篇: tabula-java_Java Fil