Tomcat学习笔记之启动分析(生命周期)(三)
2019-05-07 本文已影响0人
夏目手札
前言
在Catalina启动完成后,接下来就应该是Server的启动分析,但是由于后面的组件都与Lifecycle密不可分,所以这里先介绍Lifecycle机制。
生命周期
从上一篇文章中提到的#createStartDigester()方法中我们知道,Server的默认实现类是StandardServer,以StandardServer为入口,来看下Tomcat组件的生命周期类接口设计。

简单介绍(该图的接口跟9.0版本有少许区别):
- Lifecycle:定义了容器生命周期、容器状态转换及容器状态迁移事件的监听器注册和移除等主要接口;
- LifecycleBase:作为Lifecycle接口的抽象实现类,运用抽象模板模式将所有容器的生命周期及状态转换衔接起来,此外还提供了生成LifecycleEvent事件的接口;
- LifecycleSupport:提供有关LifecycleEvent事件的监听器注册、移除,并且使用经典的监听器模式,实现事件生成后触达监听器的实现;Tomcat9.0中已经被移除了;
- MBeanRegistration:Java JMX框架提供的注册MBean的接口,引入此接口是为了便于使用JMX提供的管理功能;
- LifecycleMBeanBase:Tomcat提供的对MBeanRegistration的抽象实现类,运用抽象模板模式将所有容器统一注册到JMX;
Lifecycle
直接来看Lifecycle接口中所包含的方法:
public interface Lifecycle {
//省略生命周期状态。。。
/**
* 添加一个生命周期监听器到组件
*/
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;
/**
* 获取当前组件的状态 返回LifecycleState对象
*/
public LifecycleState getState();
/**
* 获取当前组件的状态 返回String
*/
public String getStateName();
}
这里省略了生命周期状态的定义,源码注释上有着很好的解释几种状态的转换关系:
* start()
* -----------------------------
* | |
* | init() |
* NEW -»-- INITIALIZING |
* | | | | ------------------«-----------------------
* | | |auto | | |
* | | \|/ start() \|/ \|/ auto auto stop() |
* | | INITIALIZED --»-- STARTING_PREP --»- STARTING --»- STARTED --»--- |
* | | | | |
* | |destroy()| | |
* | --»-----«-- ------------------------«-------------------------------- ^
* | | | |
* | | \|/ auto auto start() |
* | | STOPPING_PREP ----»---- STOPPING ------»----- STOPPED -----»-----
* | \|/ ^ | ^
* | | stop() | | |
* | | -------------------------- | |
* | | | | |
* | | | destroy() destroy() | |
* | | FAILED ----»------ DESTROYING ---«----------------- |
* | | ^ | |
* | | destroy() | |auto |
* | --------»----------------- \|/ |
* | DESTROYED |
* | |
* | stop() |
* ----»-----------------------------»------------------------------
Lifecycle中用到了LifecycleListener,下面来看下:
public interface LifecycleListener {
public void lifecycleEvent(LifecycleEvent event);
}
这里之定义了一个#lifecycleEvent()方法,接下来我们来看下LifecycleEvent类:
public final class LifecycleEvent extends EventObject {
public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {
super(lifecycle);
this.type = type;
this.data = data;
}
/**
* 与此事件关联的事件数据
*/
private final Object data;
/**
* 此实例表示的事件类型
*/
private final String type;
public Object getData() {
return data;
}
/**
* 获取事件最初发生的对象,父类中定义的
*/
public Lifecycle getLifecycle() {
return (Lifecycle) getSource();
}
public String getType() {
return this.type;
}
}
LifecycleEvent类中主要定义了事件类型、事件关联的事件数据以及事件最初发生的对象。
LifecycleBase
/**
* 用于事件通知的已注册LifecycleListener列表
*/
private final List<LifecycleListener> lifecycleListeners = new CopyOnWriteArrayList<>();
/**
* 当前组件的状态,默认NEW,即对应LifecycleEvent为null
*/
private volatile LifecycleState state = LifecycleState.NEW;
private boolean throwOnFailure = true;
@Override
public void addLifecycleListener(LifecycleListener listener) {
lifecycleListeners.add(listener);
}
@Override
public LifecycleListener[] findLifecycleListeners() {
return lifecycleListeners.toArray(new LifecycleListener[0]);
}
@Override
public void removeLifecycleListener(LifecycleListener listener) {
lifecycleListeners.remove(listener);
}
/**
* 允许子类通知所有已注册的LifecycleListener
*
*/
protected void fireLifecycleEvent(String type, Object data) {
LifecycleEvent event = new LifecycleEvent(this, type, data);
for (LifecycleListener listener : lifecycleListeners) {
listener.lifecycleEvent(event);
}
}
@Override
public final synchronized void init() throws LifecycleException {
if (!state.equals(LifecycleState.NEW)) {
invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
}
try {
//1. 设置状态为before_init,并通知所有已注册的LifecycleListener
setStateInternal(LifecycleState.INITIALIZING, null, false);
//2. 模板方法,子类实现
initInternal();
//3. 设置状态为after_init,并通知所有已注册的LifecycleListener
setStateInternal(LifecycleState.INITIALIZED, null, false);
} catch (Throwable t) {
handleSubClassException(t, "lifecycleBase.initFail", toString());
}
}
@Override
public final synchronized void start() throws LifecycleException {
//1. 判断状态是否适合启动
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;
}
//2. 如果状态是NEW,重新init();如果状态是FAILED,直接stop()
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 {
//3. 设置状态为before_start,并通知所有已注册的LifecycleListener
setStateInternal(LifecycleState.STARTING_PREP, null, false);
//4. 模板方法,子类实现
startInternal();
//5. 再判断一次装态,如果正常启动成功,设置状态为after_start,并通知所有已注册的LifecycleListener
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.
handleSubClassException(t, "lifecycleBase.startFail", toString());
}
}
这里主要实现了#init()和#start()方法,并通过模板方法#xxxInternal()留给子类实现。
总结
通过上面的介绍,我们了解到Tomcat生命周期过程,Tomcat将内部所有组件都抽象为容器,使用Lifecycle接口和LifecycleBase抽像实现类为容器提供统一的生命周期管理,各个子容器只需要关心各自的具体实现,便于以后扩展更多的容器。