码迷,mamicode.com
首页 > 其他好文 > 详细

Jetty - Container源码分析

时间:2018-01-26 22:48:43      阅读:218      评论:0      收藏:0      [点我收藏+]

标签:imp   nbsp   顺序   blank   指定   cannot   info   能力   组件   

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

标签:imp   nbsp   顺序   blank   指定   cannot   info   能力   组件   

原文地址:https://www.cnblogs.com/lujiango/p/8361415.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!