您的位置:首页 > 运维架构 > Tomcat

Tomcat 源码阅读(八)Lifecycle

2017-09-30 11:46 281 查看
环境:tomcat7.0.28
坚持一下,把源码看完,勤奋一点,不要在懒惰了,你已经落下别人很多了

本文主要介绍Tomcat的生命周期模型 Lifecycle

一、Lifecycle介绍

1、Lifecycle的状态枚举类LifecycleState

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),
/**
* @deprecated Unused. Will be removed in Tomcat 9.0.x. The state transition
*             checking in {@link org.apache.catalina.util.LifecycleBase}
*             makes it impossible to use this state. The intended behaviour
*             can be obtained by setting the state to
*             {@link LifecycleState#FAILED} in
*             <code>LifecycleBase.startInternal()</code>
*/
@Deprecated
MUST_STOP(true, null),
/**
* @deprecated Unused. Will be removed in Tomcat 9.0.x. The state transition
*             checking in {@link org.apache.catalina.util.LifecycleBase}
*             makes it impossible to use this state. The intended behaviour
*             can be obtained by implementing {@link Lifecycle.SingleUse}.
*/
@Deprecated
MUST_DESTROY(false, null);

private final boolean available;//
private final String lifecycleEvent;

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

/**
* May the public methods other than property getters/setters and lifecycle
* methods be called for a component in this state? It returns
* <code>true</code> for any component in any of the following states:
* <ul>
* <li>{@link #STARTING}</li>
* <li>{@link #STARTED}</li>
* <li>{@link #STOPPING_PREP}</li>
* <li>{@link #MUST_STOP}</li>
* </ul>
*/
public boolean isAvailable() {
return available;
}

/**
*
*/
public String getLifecycleEvent() {
return lifecycleEvent;
}
}

2、Lifecycle接口定义

public interface Lifecycle {

// ----------------------------------------------------- Manifest Constants

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";

// --------------------------------------------------------- Public Methods

public void addLifecycleListener(LifecycleListener listener);
public LifecycleListener[] findLifecycleListeners();
public void removeLifecycleListener(LifecycleListener listener);

public void init() throws LifecycleException;

public void start() throws LifecycleException;

public void stop() throws LifecycleException;

public void destroy() throws LifecycleException;

public LifecycleState getState();

public String getStateName();

public interface SingleUse {
}
}

3、lifecycle生命周期流程图



二、LifecycleBase 介绍

LifecycleBase  是Lifecycle接口的抽象实现类。

1、LifecycleBase.setStateInternal方法解析

private synchronized void setStateInternal(LifecycleState state,
Object data, boolean check) throws LifecycleException {

if (log.isDebugEnabled()) {
log.debug(sm.getString("lifecycleBase.setState", this, state));
}

if (check) {
// Must have been triggered by one of the abstract methods (assume
// code in this class is correct)
// null is never a valid state
if (state == null) {
invalidTransition("null");
// Unreachable code - here to stop eclipse complaining about
// a possible NPE further down the method
return;
}

// Any method can transition to failed
// startInternal() permits STARTING_PREP to STARTING
// stopInternal() permits STOPPING_PREP to STOPPING and FAILED to
// STOPPING
if (!(state == LifecycleState.FAILED ||
(this.state == LifecycleState.STARTING_PREP &&
state == LifecycleState.STARTING) ||
(this.state == LifecycleState.STOPPING_PREP &&
state == LifecycleState.STOPPING) ||
(this.state == LifecycleState.FAILED &&
state == LifecycleState.STOPPING))) {
// No other transition permitted
invalidTransition(state.name());
}
}

this.state = state;
String lifecycleEvent = state.getLifecycleEvent();
if (lifecycleEvent != null) {
fireLifecycleEvent(lifecycleEvent, data);
}
}
该方法用于组件设置生命周期状态的时候进行状态的检查,并且触发生命周期事件。如果是不合理的状态之间进行切换,则会抛出异常。

重点来看函数fireLifecycleEvent

2、LifecycleBase.fireLifecycleEvent

protected void fireLifecycleEvent(String type, Object data) {
lifecycle.fireLifecycleEvent(type, data);
}
private LifecycleSupport lifecycle = new LifecycleSupport(this);


LifecycleSupport.fireLifecycleEvent方法:

public void fireLifecycleEvent(String type, Object data) {

LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
LifecycleListener interested[] = listeners;
for (int i = 0; i < interested.length; i++)
interested[i].lifecycleEvent(event);

}

当改变Lifecycle的子类的生命周期状态的时候,会触发生命周期事件,也就是LifecycleEvent,最终会调用LifecycleListener的lifecycleEvent事件。

listeners 是一个数组,在LifecycleSupport中定义了一个线程安全的addLifecycleListener 的方法,实现逻辑是 “写时复制”。

3、LifecycleBase.init 和 start方法解析

public final synchronized void init() throws LifecycleException {
if (!state.equals(LifecycleState.NEW)) {
invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
}

try {
setStateInternal(LifecycleState.INITIALIZING, null, false);
initInternal();
setStateInternal(LifecycleState.INITIALIZED, null, false);
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
setStateInternal(LifecycleState.FAILED, null, false);
throw new LifecycleException(
sm.getString("lifecycleBase.initFail",toString()), t);
}
}

protected abstract void initInternal() throws LifecycleException;

/**
* {@inheritDoc}
*/
@Override
public final synchronized void start() throws LifecycleException {

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;
}

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 {
 setStateInternal(LifecycleState.STARTING_PREP, null, false);
startInternal();
if (state.equals(LifecycleState.FAILED)) {
// This is a 'controlled' failure. The component put itself into the
// FAILED state so call stop() to complete the clean-up.
stop();
} else if (!state.equals(LifecycleState.STARTING)) {
// Shouldn't be necessary but acts as a check that sub-classes are
// doing what they are supposed to.
invalidTransition(Lifecycle.AFTER_START_EVENT);
} else {
setStateInternal(LifecycleState.STARTED, null, false);
}
} catch (Throwable t) {
// This is an 'uncontrolled' failure so put the component into the
// FAILED state and throw an exception.
ExceptionUtils.handleThrowable(t);
setStateInternal(LifecycleState.FAILED, null, false);
throw new LifecycleException(sm.getString("lifecycleBase.startFail", toString()), t);
}
}

/**
* Sub-classes must ensure that the state is changed to
* {@link LifecycleState#STARTING} during the execution of this method.
* Changing state will trigger the {@link Lifecycle#START_EVENT} event.
*
* If a component fails to start it may either throw a
* {@link LifecycleException} which will cause it's parent to fail to start
* or it can place itself in the error state in which case {@link #stop()}
* will be called on the failed component but the parent component will
* continue to start normally.
*
* @throws LifecycleException
*/
protected abstract void startInternal() throws LifecycleException;

通过LifecycleBase 的init 方法可以看出,在任何生命周期组件的初始化过程中,都需要先设置组件的生命周期状态为初始化正在进行的状态,调用初始化中状态事件,然后调用初始化方法,最后再设置一下初始化完毕的状态,调用完毕状态的事件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: