1 Tomcat中的组件
Tomcat里面有各种各样的组件,每个组件各司其职,组件之间又相互协作共同完成web服务器这样的工程。
组件关系
如果你仔细分析过这些组件,可以发现它们具有两层关系。
第一层关系是组件有大有小,大组件管理小组件,比如 Server 管理 Service,Service 又管理连接器(Connector)和容器(Engline)。
第二层关系是组件有外有内,外层组件控制内层组件,比如连接器(Connector)是外层组件,负责对外交流,外层组件调用容器(Engline)组件完成业务功能。也就是说,请求的处理过程是由外层组件来驱动的。
2 Lifecycle 接口
2.1 Lifecycle设计原则
如果想让一个系统中组件能够对外提供服务,我们需要在服务启动时,为每个组进行创建,初始化,启动。同时在服务停止的时候,我们还需要每个组件在停止前释放资源,销毁这些组件。也就是说,Tomcat 需要动态地管理这些组件的生命周期。
所谓设计就是要找到系统的变化点和不变点。这里的不变点就是每个组件都要经历创建、初始化、启动这几个过程,这些状态以及状态的转化是不变的。而变化点是每个具体组件具体的实现。
因此,我们把不变点抽象出来成为一个接口,这个接口跟生命周期有关,叫作 Lifecycle。Lifecycle接口里应该定义这么几个方法:init、start、stop 和 destroy,每个具体的组件去实现这些方法。
2.2 Lifecycle接口
public interface Lifecycle {
....
// 初始化方法
public void init() throws LifecycleException;
// 启动方法
public void start() throws LifecycleException;
// 停止方法,和start对应
public void stop() throws LifecycleException;
// 销毁方法,和init对应
public void destroy() throws LifecycleException;
// 获取生命周期状态
public LifecycleState getState();
// 获取字符串类型的生命周期状态
public String getStateName();
}
2.3 Lifecycle实现一键启动
在这样的设计中,在父组件的 init 方法里需要创建子组件并调用子组件的 init 方法。同样,在父组件的 start 方法里也需要调用子组件的 start 方法。因此调用者可以无差别的调用各组件的 init 方法和 start 方法,这就是组合模式的使用,并且只要调用最顶层组件,也就是 Server 组件的 init 和 start 方法,整个 Tomcat 就被启动起来了。
3 Lifecycle 事件监听机制
3.1 事件监听机制
因为各个组件 init 和 start 方法的具体实现是复杂多变的。比如在 Host 容器的启动方法里需要扫描 webapps 目录下的 Web 应用,创建相应的 Context 容器,如果将来需要增加新的逻辑,直接修改 start 方法?这样会违反开闭原则,那如何解决这个问题呢?开闭原则说的是为了扩展系统的功能,你不能直接修改系统中已有的类,但是你可以定义新的类,这样可以大大降低系统修改的风险。
Lifecycle通过引入事件监听机制,一个组件函数业务处理可以通过添加监听器的方式实现对组件业务安全的动态扩展。
3.2 实现原理
那么这里我们把组件的生命周期定义成一个个状态,把状态的转变看作是一个事件。
public enum LifecycleState {
//实例化完成时的状态
NEW(false, null),
// 容器正在初始化的状态,在INITIALIZED之前
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;
}
/**
* 判断组件是否正在运行
*/
public boolean isAvailable() {
return available;
}
/**
* 返回组件当前状态需要触发的事件
*/
public String getLifecycleEvent() {
return lifecycleEvent;
}
}
事件是有监听器的,每个组件都内部都可以维护管理一组监听器,在事件触发后监听器里可以实现一些逻辑。
public interface Lifecycle {
// 添加监听器
public void addLifecycleListener(LifecycleListener listener);
// 获取所以监听器
public LifecycleListener[] findLifecycleListeners();
// 移除某个监听器
public void removeLifecycleListener(LifecycleListener listener);
...
}
[图片上传失败...(image-747a5d-1565247652167)]
3 LifecycleBase基类
有了接口,我们就要用类去实现接口。一般来说实现类不止一个,不同的类在实现接口时往往会有一些相同的逻辑,如果让各个子类都去实现一遍,就会有重复代码。那子类如何重用这部分逻辑呢?其实就是定义一个基类来实现共同的逻辑,然后让各个子类去继承它,就达到了重用的目的。
Tomcat 定义一个基类LifecycleBase 来实现 Lifecycle 接口,把一些公共的逻辑放到基类中去,比如生命状态的转变与维护、生命事件的触发以及监听器的添加和删除等,而子类就负责实现自己的初始化、启动和停止等方法。为了避免跟基类中的方法同名,我们把具体子类的实现方法改个名字,在后面加上 Internal,叫 initInternal、startInternal 等。
从图上可以看到,LifecycleBase 实现了 Lifecycle 接口中所有的方法,还定义了相应的抽象方法交给具体子类去实现,这是典型的模板设计模式。
3.1 监听器管理的实现
/**
* 管理当前组件生命周期监听器列表
*/
private final List lifecycleListeners = new CopyOnWriteArrayList<>();
/**
* 给当前组件添加一个生命周期监听器
*/
@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);
}
3.2 事件的触发
/**
* 触发一个生命周期事件,通知所有生命周期监听器触发
*
* @param type Event type
* @param data Data associated with event.
*/
protected void fireLifecycleEvent(String type, Object data) {
LifecycleEvent event = new LifecycleEvent(this, type, data);
for (LifecycleListener listener : lifecycleListeners) {
listener.lifecycleEvent(event);
}
}
3.3 生命状态的转变与维护(状态机)
3.1.1 组件初始化
/**
* 组件初始化动作,所有组件通用操作
* 1 检查校验当前组件状态是否能够初始化
* 2 修改当前的状态从 NEW-->INITIALIZING
* 3 调用每个组件模板方法实现完成初始化动作
* 4 修改当前的状态从 INITIALIZING-->INITIALIZED
*/
@Override
public final synchronized void init() throws LifecycleException {
/** 非NEW状态,不允许调用init()方法 **/
if (!state.equals(LifecycleState.NEW)) {
/** 从sm获取"lifecycleBase.invalidTransition"属性对应日志格式,抛出LifecycleException异常 **/
invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
}
try {
/** 初始化逻辑之前,将状态变更为`INITIALIZING` **/
setStateInternal(LifecycleState.INITIALIZING, null, false);
/** 初始化组件,该方法为一个abstract模板方法,需要组件自行实现 **/
initInternal();
/** 初始化完成之后,状态变更为`INITIALIZED` **/
setStateInternal(LifecycleState.INITIALIZED, null, false);
}
/** 初始化的过程中,可能会有异常抛出,这时需要捕获异常,并将状态变更为`FAILED` **/
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;
3.1.2 组件启动
/**
* 组件启动动作,所有组件通用操作
*/
@Override
public final synchronized void start() throws LifecycleException {
/** 组件当前状态为`STARTING_PREP`、`STARTING`和`STARTED时,将忽略start()逻辑 **/
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()方法 **/
if (state.equals(LifecycleState.NEW)) {
init();
}
/** 组件当前状态为`FAILED`时,执行stop()方法 **/
else if (state.equals(LifecycleState.FAILED)) {
stop();
}
/** 组件当前状态不是`INITIALIZED`和`STOPPED`时,则说明是非法的操作,抛出异常**/
else if (!state.equals(LifecycleState.INITIALIZED) &&
!state.equals(LifecycleState.STOPPED)) {
/** 从sm获取"lifecycleBase.invalidTransition"属性对应日志格式,抛出LifecycleException异常 **/
invalidTransition(Lifecycle.BEFORE_START_EVENT);
}
try {
/** 启动逻辑之前,先将状态变更为`STARTING_PREP` **/
setStateInternal(LifecycleState.STARTING_PREP, null, false);
/** 启动组件,该方法为一个abstract模板方法,需要组件自行实现 **/
startInternal();
/** 如果启动组件发生异常状态被更新为'FAILED',调用stop() **/
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();
}
/** 如果启动组件后状态未被更新为STARTING,抛出异常 **/
else if (!state.equals(LifecycleState.STARTING)) {
/** 从sm获取"lifecycleBase.invalidTransition"属性对应日志格式,抛出LifecycleException异常 **/
invalidTransition(Lifecycle.AFTER_START_EVENT);
}
/** 启动完成,将状态变更为`STARTED` **/
else {
setStateInternal(LifecycleState.STARTED, null, false);
}
}
/** 初始化的过程中,可能会有异常抛出,这时需要捕获异常,并将状态变更为`FAILED` **/
catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
setStateInternal(LifecycleState.FAILED, null, false);
throw new LifecycleException(sm.getString("lifecycleBase.startFail", toString()), t);
}
}
/**
* 启动模板方法
*/
protected abstract void startInternal() throws LifecycleException;
3.1.3 组件停止
/**
* 组件停止化动作,所有组件通用操作
*/
@Override
public final synchronized void stop() throws LifecycleException {
/** 组件状态为`STOPPING_PREP`、`STOPPING`和`STOPPED'时,将忽略start()逻辑 **/
if (LifecycleState.STOPPING_PREP.equals(state) || LifecycleState.STOPPING.equals(state) ||
LifecycleState.STOPPED.equals(state)) {
if (log.isDebugEnabled()) {
Exception e = new LifecycleException();
log.debug(sm.getString("lifecycleBase.alreadyStopped", toString()), e);
} else if (log.isInfoEnabled()) {
log.info(sm.getString("lifecycleBase.alreadyStopped", toString()));
}
return;
}
/** 组件当前状态`NEW`时,直接将状态变更为`STOPPED` **/
if (state.equals(LifecycleState.NEW)) {
state = LifecycleState.STOPPED;
return;
}
/** 组件当前状态不是`STARTED`和`FAILED`时,则说明是非法的操作,抛出异常**/
if (!state.equals(LifecycleState.STARTED) && !state.equals(LifecycleState.FAILED)) {
/** 从sm获取"lifecycleBase.invalidTransition"属性对应日志格式,抛出LifecycleException异常 **/
invalidTransition(Lifecycle.BEFORE_STOP_EVENT);
}
try {
/** 组件当前状态为`FAILED`时,直接触发BEFORE_STOP_EVENT事件 **/
if (state.equals(LifecycleState.FAILED)) {
fireLifecycleEvent(BEFORE_STOP_EVENT, null);
} else {
/** 停止逻辑之前,先将状态变更为`STOPPING_PREP` **/
setStateInternal(LifecycleState.STOPPING_PREP, null, false);
}
/** 停止组件,该方法为一个abstract模板方法,需要组件自行实现 **/
stopInternal();
/** 停止组件后,当前状态不是`STOPPING`,`FAILED`抛出异常 **/
if (!state.equals(LifecycleState.STOPPING) && !state.equals(LifecycleState.FAILED)) {
/** 从sm获取"lifecycleBase.invalidTransition"属性对应日志格式,抛出LifecycleException异常 **/
invalidTransition(Lifecycle.AFTER_STOP_EVENT);
}
/** 停止完成,将状态变更为`STOPPED` **/
setStateInternal(LifecycleState.STOPPED, null, false);
}
/** 初始化的过程中,可能会有异常抛出,这时需要捕获异常,并将状态变更为`FAILED` **/
catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
setStateInternal(LifecycleState.FAILED, null, false);
throw new LifecycleException(sm.getString("lifecycleBase.stopFail",toString()), t);
} finally {
/** 当前组件是SingleUse子类设置状态为'STOPPED' **/
if (this instanceof Lifecycle.SingleUse) {
// Complete stop process first
setStateInternal(LifecycleState.STOPPED, null, false);
destroy();
}
}
}
/**
* 停止模板方法
*/
protected abstract void stopInternal() throws LifecycleException;
3.1.4 组件的销毁
/**
* 组件销毁动作,所有组件通用操作
*/
@Override
public final synchronized void destroy() throws LifecycleException {
/** 组件当前状态为`FAILED`状态时,直接触发stop()逻辑 **/
if (LifecycleState.FAILED.equals(state)) {
try {
// Triggers clean-up
stop();
} catch (LifecycleException e) {
// Just log. Still want to destroy.
log.warn(sm.getString(
"lifecycleBase.destroyStopFail", toString()), e);
}
}
/** 当前状态为 `DESTROYING`和`DESTROYED`时,忽略destroy的执行 **/
if (LifecycleState.DESTROYING.equals(state) ||
LifecycleState.DESTROYED.equals(state)) {
if (log.isDebugEnabled()) {
Exception e = new LifecycleException();
log.debug(sm.getString("lifecycleBase.alreadyDestroyed", toString()), e);
} else if (log.isInfoEnabled() && !(this instanceof Lifecycle.SingleUse)) {
// Rather than have every component that might need to call
// destroy() check for SingleUse, don't log an info message if
// multiple calls are made to destroy()
log.info(sm.getString("lifecycleBase.alreadyDestroyed", toString()));
}
return;
}
/** 非法状态判断,抛出异常 **/
if (!state.equals(LifecycleState.STOPPED) &&
!state.equals(LifecycleState.FAILED) &&
!state.equals(LifecycleState.NEW) &&
!state.equals(LifecycleState.INITIALIZED)) {
/** 从sm获取"lifecycleBase.invalidTransition"属性对应日志格式,抛出LifecycleException异常 **/
invalidTransition(Lifecycle.BEFORE_DESTROY_EVENT);
}
try {
/** 销毁逻辑之前,将状态变更为`DESTROYING` **/
setStateInternal(LifecycleState.DESTROYING, null, false);
/** 停止组件,该方法为一个abstract模板方法,需要组件自行实现 **/
destroyInternal();
/** 销毁完成,将状态变更为`DESTROYED` **/
setStateInternal(LifecycleState.DESTROYED, null, false);
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
setStateInternal(LifecycleState.FAILED, null, false);
throw new LifecycleException(
sm.getString("lifecycleBase.destroyFail",toString()), t);
}
}
protected abstract void destroyInternal() throws LifecycleException;
3.4 其他方法
/**
* 获取当前组件状态
*/
@Override
public LifecycleState getState() {
return state;
}
/**
* 获取当前组件状态名称
*/
@Override
public String getStateName() {
return getState().toString();
}
/**
* 更新当前组件的状态
*/
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);
}
/**
* 更新当前组件的状态
* @param state 更新的状态
* @param data 触发事件数据
* @param check 是否对组件状态更新做检查
* @throws LifecycleException
*/
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) {
/** 检查当前状态是否为nul **/
if (state == null) {
/** 从sm获取当前日志格式,抛出LifecycleException异常 **/
invalidTransition("null");
return;
}
/** 检查状态变更逻辑是否错误 **/
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))) {
/** 从sm获取当前日志格式,抛出LifecycleException异常 **/
invalidTransition(state.name());
}
}
/** 更新当前组件状态 **/
this.state = state;
String lifecycleEvent = state.getLifecycleEvent();
/** 获取更新状态需要触发的事件 **/
if (lifecycleEvent != null) {
fireLifecycleEvent(lifecycleEvent, data);
}
}