在tomcat中起到生命周期的核心接口是Lifecycle看一下这个接口的方法签名:
这个接口定义了所有组件可能处于的所有状态、增加获取删除监听器操作、组件初始化,开启,停止,注销操作和获取当前状态操作。
在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),
MUST_STOP(true, null),
MUST_DESTROY(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;
}
}
从以上源码可见LifecycleState枚举类就是对Lifecycle接口中的状态进行了封装。另外加了是否可用标志。
下面从我们所熟悉的StandardServer类入手开始讨论这些组件是怎么被初始化以及怎么被开启的。看一下StandardServer的继承图解:
至此就引出了一个问题,LifecycleBase是个什么类。打开这个类的源码首先可以看到它实现了Lifecycle接口,即它是管理组件生命周期的最顶层的类。一般像这种高层次的类都是抽象的,这个类也不例外,它也是抽象的。
下面开始讨论这个类的方法,首先继承LifecycleBase的底层组件类比如StandardServer它是不需要重写init,start,stop这三个方法的。因为这三个方法定义了组件状态转换的共性。比如init方法,所有组件在初始化时都要执行这个公共方法。先贴一下这个方法的源码:
@Override
public final synchronized void init() throws LifecycleException {
if (!state.equals(LifecycleState.NEW)) {
invalidTransition(Lifecycle.BEFORE_INIT_EVENT);
}
setStateInternal(LifecycleState.INITIALIZING, null, false);
try {
initInternal();
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
setStateInternal(LifecycleState.FAILED, null, false);
throw new LifecycleException(
sm.getString("lifecycleBase.initFail",toString()), t);
}
setStateInternal(LifecycleState.INITIALIZED, null, false);
}
其中有两点需要重点关注:
1)setStateInternal:该方法的作用是重新设置该组件的状态。并且在状态改变时还伴随着事件监听器的执行。查看setStateInternal的代码不难发现它的核心代码如下:
this.state = state;
String lifecycleEvent = state.getLifecycleEvent();
if (lifecycleEvent != null) {
fireLifecycleEvent(lifecycleEvent, data);
}
先改变组件状态,然后查看该状态是否需要被监听器监听。如果被监听器监听就执行监听器。但是执行监听器说起来容易,它是怎么来的,它的监听机制又是什么?
现在追上这个方法看看它的实现过程:
protected void fireLifecycleEvent(String type, Object data) {
lifecycle.fireLifecycleEvent(type, data);
}
这个lifecycle又是什么东西?它是LifecycleSupport类的一个实例。其实LifecycleBase是LifecycleSupport的一个代理类。所有监听器有关的方法LifecycleBase都是调用的LifecycleSupport中的方法。可以看一下LifecycleSupport的方法签名:
lifecycle是指该LifecycleSupport类是为哪个实现lifecycle接口的类服务的。listeners[]是监听器数组,addLifecycleListener是增加监听器,在tomcat容器启动时,使用Digester技术(没听过没关系,只要知道它是读取配置文件然后根据配置文件实例化对象就行)读取server.xml文件中的<Listener>标签,然后调用addLifecycleListener将配置的Listener添加到listeners[]中。removeLifecycleListener是移出监听器。fireLifecycleEvent是循环执行监听器数组中的每一个监听器。上面谈到的状态改变时就是执行的这个fireLifecycleEvent方法。
看到这里也许有的朋友已经忘了上文的init方法了,千万注意到此这只是谈到init方法中需要注意两点的第一点。那么现在开始第二点:
2)initInternal方法。它是个抽象方法也就是说该方法必须由子类重写。首先看它的直接子类LifecycleMBeanBase。看到这类的名字就能想到它可能与javabean管理有关。的确他复写了initInternal方法,其目的就是将该组件注册到JMX服务器中。对于具体注册过程先不做过多讨论,之后更新还会详细说明。StandardServer也重写了initInternal方法。并且第一行是:
super.initInternal();
调用父类也就是LifecycleMBeanBase类中的initInternal方法,这时候这句话是万万不能省的,如果省了就不能向JMX服务器注册对象了。这一点要跟eclipse中自动生成构造方法第一行super.init();可写可不写区分开。在子类中重点代码如下:
// Initialize our defined Services
for (int i = 0; i < services.length; i++) {
services[i].init();
}
它执行了service的init方法。仔细回故上面的逻辑,整理一下思路,会发现tomcat的生命周期管理是何等的漂亮!
我将tomcat生命周期的实现过程从tomcat源码中抽离了出来,建立了一个小的Demo,有兴趣的朋友可以下载debug以此来整理思路,这样会更加直观。
地址:
https://github.com/smallbug-vip/repo
- 大小: 6.9 KB
- 大小: 3.4 KB
- 大小: 4.4 KB
分享到:
相关推荐
tomcat7源码下载tomcat7源码下载tomcat7源码下载tomcat7源码下载tomcat7源码下载tomcat7源码下载tomcat7源码下载tomcat7源码下载
tomcat7的源码项目,可以导入到eclipse,自己编译运行tomcat。
这些资源文档是本人在网上搜索了好多关于tomcat源码讲解的文章之后,觉得对tomcat6源码讲解不错的文章的整理,文档有别人分析,本人只是整理;
Tomcat初始化流程分析,Tomcat启动流程分析 Tomcat处理一次请求过程分析 servlet初始化流程
介绍了tomcat的架构,从源码分析tomcat组成!
tomcat 源码分析系列文档 http深入分析,tomcat中类的加载,tomcat的启动,tomcat的容器思想,
apache-tomcat-7.0.42,包含了tomcat-7.0.42源码和内存配置
Spring源码分析,web源码分析,Tomcat架构源码分析都是非常深入的源码级课程,期待研究设计模式和深入学习源码内功的朋友们,一定要仔细的学习研究。 (0);目录中文件数:1个 ├─3.代码.zip (1)\1.笔记;目录中文...
tomcat的基础脚本分析 tomcat的源码启动分析 tomcat的web应用启动分析 tomcat的socket分析 tomcat的cocket与容器对接时序分析
tomcat 7.0 源码
tomcat8.0源码
Tomcat与JavaWeb开发技术详解-随书源码
tomcat7源码调试,需要把tomcat编程maven工程所需要的pom文件
tomcat7 源码
Tomcat源码Tomcat源码Tomcat源码Tomcat源码Tomcat源码Tomcat源码Tomcat源码
tomcat7.0.42源码,eclipse直接使用,tomcat7.0.42源码,eclipse直接使用
Tomcat与JavaWeb开发技术详解书本的源代码。
tomcat6的源码,官网下载!适合放在eclipse
NULL 博文链接:https://utopialxw.iteye.com/blog/1624763