在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
分享到:
相关推荐
### Tomcat架构的源码分析 #### 一、Tomcat的架构概述 Tomcat作为一款广泛使用的开源Java Servlet容器,其内部架构设计简洁而高效。本文档将对Tomcat的架构进行详细介绍,并从源码层面深入分析其核心组成部分。...
### Tomcat7源码手撕过程详解 #### Tomcat初始化流程分析 Tomcat是一个流行的Java Servlet容器,用于部署和运行Web应用程序。理解Tomcat的工作原理对于优化应用性能、解决部署问题至关重要。以下是对Tomcat7启动...
7. "tomcat源码分析之一架构.pdf":可能涵盖了Tomcat的整体架构,包括Catalina、 Coyote、Jasper等主要模块的功能和相互关系。 8. "HTTP协议详解.pdf":作为基础,此文档提供了HTTP协议的详细讲解,帮助读者理解...
《Tomcat源码分析1——服务启动与架构详解》 Tomcat,作为一款广泛应用的开源Java Servlet容器,其内部架构和启动流程对于深入理解和优化Web应用程序至关重要。本文将重点解析Tomcat启动时的关键步骤和核心组件,...
### Tomcat源码分析 #### 一、概述 Apache Tomcat是Java开发人员最常用的Web服务器之一,它不仅能够作为独立的应用程序运行Servlet和JavaServer Pages(JSP),还可以作为一个内嵌的容器来运行Web应用。Tomcat的...
### Tomcat源码研究知识点概览 #### 1.1 Catalina.bat脚本解析 - **脚本功能**:`catalina.bat`是Tomcat启动过程中的关键脚本之一,其主要作用在于构建合适的Java命令行参数,进而启动Tomcat服务。此脚本根据环境...
《Tomcat与Java Web开发技术详解(第二版)》是由知名IT专家孙卫琴编著的一本深入解析Java Web开发和Tomcat服务器使用的经典教材。该书覆盖了从基础到高级的众多主题,旨在帮助开发者全面理解如何在Tomcat上构建、...
5. **Tomcat源码分析** 对于Tomcat的实现细节,主要关注以下几点: - **启动/初始化**:Tomcat启动时会解析web.xml,创建并初始化应用的组件。 - **并发线程模式**:Tomcat使用线程池来处理并发请求,提高性能。 ...
Maven的生命周期包括清理、编译、测试、打包、验证、安装和部署等阶段。 2. **Tomcat7.0.78详解**:这个版本的Tomcat引入了许多改进和修复,包括性能优化、安全性增强以及对Servlet、JSP和EL规范的支持。它支持Java...
2. **生命周期管理**:在Catalina模块中,`Container`接口和`LifeCycle`接口代表了Tomcat中的组件和它们的生命周期方法,如`start()`、`stop()`等,这对于理解和控制服务器启动和停止过程至关重要。 3. **部署与...
1. **基础教程**:解释Java Web开发的基本概念,如Servlet和JSP的生命周期,以及它们如何与Tomcat交互。 2. **实战项目**:提供实际的Web应用示例,帮助开发者实践所学知识,可能包括登录系统、新闻发布系统等。 3. ...
五、容器与源码分析 了解了容器的基本概念后,对于开发者来说,阅读Tomcat的源码可以帮助更深入地理解容器的工作原理。Tomcat的源码组织清晰,通过跟踪ContainerBase、StandardEngine、StandardHost、...
1. **Tomcat源码**:Tomcat的源代码对于理解其工作原理至关重要。开发者可以通过阅读源码学习如何处理HTTP请求,管理会话,以及如何部署和执行Java Web应用。源码中的关键组件如Catalina(核心引擎)、Coyote(处理...
源码中可以看到Valve的生命周期管理和配置。 9. **性能优化**: 通过对源码的研究,可以了解到Tomcat如何缓存静态资源、管理会话、优化线程调度等,从而针对性地进行性能优化。 10. **错误处理与调试**: Tomcat...
每个Container都有自己的生命周期管理,负责创建、初始化、启动、停止和销毁其子组件。 - **Pipeline与Valve**: Pipeline是容器内部请求处理的流水线,Valve是流水线上的一个个处理环节。Valve可以实现日志记录、...
在深入学习JSP(Java Server Pages)应用开发的过程中,源码分析是提升技能的重要环节。本资料“jsp应用开发详解源码1-4章”旨在帮助开发者通过实践代码理解JSP的核心概念和技术,从而在网站开发领域更加得心应手。 ...
【标题】"Tomcat7研究:Tomcat源码探索" 【描述】深入研究Apache Tomcat 7源码,是理解这个流行的开源Java Servlet容器内部工作原理的重要步骤。Tomcat作为一个轻量级应用服务器,广泛应用于各种Web应用程序部署,...