日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Jetty - Container源码分析

發布時間:2023/12/19 编程问答 32 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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)刪除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,不在詳細描述。?

轉載于:https://www.cnblogs.com/lujiango/p/8361415.html

總結

以上是生活随笔為你收集整理的Jetty - Container源码分析的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。