1. 程式人生 > >Jetty - Container源碼分析

Jetty - Container源碼分析

troy anr getbean started 如果 collect child rri 源碼分析

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源碼分析