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的状态转换如下
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);
}
}