tomcat之LifeCycle

tomcat里几乎所有组件都实现了LifeCycle接口,例如Server、Service、Connector、Executor、Engine、Host、Context、Wrapper
LifeCycle接口定义了这些组件的声明周期管理,包括四个声明周期方法与一系列的状态

public interface Lifecycle {
    public void init() throws LifecycleException;
    public void start() throws LifecycleException;
    public void stop() throws LifecycleException;
    public void destroy() throws LifecycleException;
}

LifeState枚举定义了一系列的状态

public enum LifecycleState {
    NEW(false, null),
    INITIALIZING(false, Lifecycle.BEFORE_INIT_EVENT),
    INITIALIZED(false, Lifecycle.AFTER_INIT_EVENT),
    STARTING_PREP(false, Lifecycle.BEFORE_START_EVENT),
    STARTING(true, Lifecycle.START_EVENT),
    STARTED(true, Lifecycle.AFTER_START_EVENT),
    STOPPING_PREP(true, Lifecycle.BEFORE_STOP_EVENT),
    STOPPING(false, Lifecycle.STOP_EVENT),
    STOPPED(false, Lifecycle.AFTER_STOP_EVENT),
    DESTROYING(false, Lifecycle.BEFORE_DESTROY_EVENT),
    DESTROYED(false, Lifecycle.AFTER_DESTROY_EVENT),
    FAILED(false, null);

    private final boolean available;
    private final String lifecycleEvent;

    private LifecycleState(boolean available, String lifecycleEvent) {
        this.available = available;
        this.lifecycleEvent = lifecycleEvent;
    }

    // getters
}

LifeCycle的状态转换如下
image.png
1、组件创建以后,状态为NEW
2、每个状态都可以直接转换到FAILED状态
3、调用init、start、stop、destroy会进行相应的状态迁移;auto的状态会自动转换;调用这些方法时会校验状态是否合法。例如只有在NEW状态下才可以调用init,只有在NEW、INITIALIZED、STOP状态下才可以调用start
4、start方法比较特殊。调用start方法会看当前是否init过,没有的话会首先init,否则直接start
5、迁移到新状态时都会发送LifecycleEvent给LifeCycleListener
LifeCycle还提供了addLifecycleListener、findLifecycleListeners、removeLifecycleListener来管理Listener

public interface Lifecycle {
	public void addLifecycleListener(LifecycleListener listener);
    public LifecycleListener[] findLifecycleListeners();
    public void removeLifecycleListener(LifecycleListener listener);
}

LifecycleListener接口也比较简单,只有lifecycleEvent一个方法,会收到一个LifecycleEvent实例。LifeCycle不会判断一个Listener对哪些Event感兴趣,而是只要有事件就会通知Listener,需要Listener自己判断是哪个事件

public interface LifecycleListener {

    public void lifecycleEvent(LifecycleEvent event);
}

Listener怎么判断是哪个事件呢? LifecycleEvent有三个属性

  • data。发送事件时,发送者传进来的数据,可null
  • type。该事件类型
  • lifecycle。产生该事件的组件,例如Server、Engine、Host等
public final class LifecycleEvent extends EventObject {
    private final Object data;
    private final String type;

    public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {
        super(lifecycle);
        this.type = type;
        this.data = data;
    }
}

Listener需要根据type判断该LifecycleEvent是哪一个事件,由此决定不处理或者做什么样的处理。这个type具体的值定义在LifeCycle接口里

public interface Lifecycle {

    public static final String BEFORE_INIT_EVENT = "before_init";
    public static final String AFTER_INIT_EVENT = "after_init";
    public static final String START_EVENT = "start";
    public static final String BEFORE_START_EVENT = "before_start";
    public static final String AFTER_START_EVENT = "after_start";
    public static final String STOP_EVENT = "stop";
    public static final String BEFORE_STOP_EVENT = "before_stop";
    public static final String AFTER_STOP_EVENT = "after_stop";
    public static final String AFTER_DESTROY_EVENT = "after_destroy";
    public static final String BEFORE_DESTROY_EVENT = "before_destroy";
    public static final String PERIODIC_EVENT = "periodic";
    public static final String CONFIGURE_START_EVENT = "configure_start";
    public static final String CONFIGURE_STOP_EVENT = "configure_stop";
}

LifeCycle是怎么处理状态转换以及调用Listener的呢?主要逻辑实现在LifecycleBase里。init、start、destroy、stop逻辑比较类似
1、首先校验当前状态是否合法,比如init方法只能在状态为NEW情况下调用,否则抛异常
2、设置状态为XXX_PRE
3、调用xxxInternal方法将具体的init、start、destroy、stop逻辑交给子类处理
4、根据子类处理的结果(子类将状态置为FAILED、子类没有按要求转换状态、子类正常处理),处理状态转换
具体看一个start逻辑

    public final synchronized void start() throws LifecycleException {

        // 如果状态STARTING_PREP、STARTING、STARTED,直接忽略
        if (LifecycleState.STARTING_PREP.equals(state) || LifecycleState.STARTING.equals(state) ||
                LifecycleState.STARTED.equals(state)) {

            if (log.isDebugEnabled()) {
                Exception e = new LifecycleException();
                log.debug(sm.getString("lifecycleBase.alreadyStarted", toString()), e);
            } else if (log.isInfoEnabled()) {
                log.info(sm.getString("lifecycleBase.alreadyStarted", toString()));
            }

            return;
        }

        // 如果状态是NEW,先init。init会确保转移的状态是正确的,不需要再次校验状态是否合法
        // 如果状态时FAILED,执行stop
        // 校验状态必须是INITIALIZED或者STOPPED,否则抛异常
        if (state.equals(LifecycleState.NEW)) {
            init();
        } else if (state.equals(LifecycleState.FAILED)) {
            stop();
        } else if (!state.equals(LifecycleState.INITIALIZED) &&
                !state.equals(LifecycleState.STOPPED)) {
            invalidTransition(Lifecycle.BEFORE_START_EVENT);
        }

        try {
            // 设置状态为STARTING_PREP,然后调用startInternal执行子类start逻辑
            setStateInternal(LifecycleState.STARTING_PREP, null, false);
            startInternal();
            if (state.equals(LifecycleState.FAILED)) {
                // 子类startInternal可以将自己状态设置为FAILED。这时执行stop
                stop();
            } else if (!state.equals(LifecycleState.STARTING)) {
                // 子类startInternal执行正常的话,必须要将状态置为STARTING,否则抛异常 
                invalidTransition(Lifecycle.AFTER_START_EVENT);
            } else {
                // 一切都正常,设置状态为STARTED
                setStateInternal(LifecycleState.STARTED, null, false);
            }
        } catch (Throwable t) {
            handleSubClassException(t, "lifecycleBase.startFail", toString());
        }
    }

什么时候调用Listener的呢?是在setStateInternal的时候会调用Listener。可以供子类调用的setState方法check为true,LifecycleBase内部调用的setStateInternal方法check设置都为false,也就是子类设置状态必须校验状态转换是否合法,内部设置则不校验

    protected synchronized void setState(LifecycleState state) throws LifecycleException {
        setStateInternal(state, null, true);
    }

    protected synchronized void setState(LifecycleState state, Object data)
            throws LifecycleException {
        setStateInternal(state, data, true);
    }

setStateInternal里调用fireLifecycleEvent方法,通知所有Listener


    private synchronized void setStateInternal(LifecycleState state, Object data, boolean check)
            throws LifecycleException {
        // 先校验转换是否合法,不合法的话抛异常

        this.state = state;
        String lifecycleEvent = state.getLifecycleEvent();
        if (lifecycleEvent != null) {
            fireLifecycleEvent(lifecycleEvent, data);
        }
    }

    protected void fireLifecycleEvent(String type, Object data) {
        LifecycleEvent event = new LifecycleEvent(this, type, data);
        for (LifecycleListener listener : lifecycleListeners) {
            listener.lifecycleEvent(event);
        }
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值