【深入剖析Tomcat笔记】第六篇 Tomcat Lifecycle
来源:互联网 发布:量化投资python教材 编辑:程序博客网 时间:2024/05/16 09:26
简述
上一篇中介绍了Tomcat四大容器,Enginee、Host、Context和Wrapper以及如何通过TaskPipeline对四大容器进行功能性扩展。在 第五篇 Tomcat Container和PipeliningTasks 中我们介绍了如何通过Pipeline Task去为Enginee添加一些共用的方法,但这样还存在一些问题,我们很难对Container实例进行管理。Composite模式的一个明显的弊端就是存在大量的子容器,难以进行管理。为了解决这个问题,本篇将以四大容器为核心介绍Tomcat的生命周期。
Event
在之前的程序中,我们对容器进行管理是通过代码来实现的。
例如
...context.start();context.execute();context.end();...
Tomcat中非常核心的一个特性是向用户提供一个容器环境实现多线程,且用户透明(用户不需要关心多线程实现)。但用户在某些高级特性时候需要介入容器的管理,此时采用代码形式进行管理不足以实现这部分功能,用户若需要介入,则需要改动tomcat源码。
Event相当于Tomcat暴露给用户的一个接口去实现这部分功能,用户在需要感知Tomcat容器时,仅仅需要实现对应的event即可。
相信熟悉Spring的小伙伴们已经对于Event已经非常熟悉了,在此简单介绍一下Event。
Event是运行状态和暴露资源的封装
JDK1.1中提供了EventObject对象实现事件驱动,在没有EventObject的情况下我们实现对象运行状态管理(例如:运行,停止、自定义….),一种方式是硬编码,这种方式无法由外部模块控制,另外一种方式是轮询,这种方式外部模块不需要感知内部状态,明显的缺点是消耗大量计算资源。EventObject很好的解决了这个问题。
以下是JDK对于EventObject介绍
/** * <p> * The root class from which all event state objects shall be derived. * <p> * All Events are constructed with a reference to the object, the "source", * that is logically deemed to be the object upon which the Event in question * initially occurred upon. * * @since JDK1.1 */public class EventObject implements java.io.Serializable { protected transient Object source; //构造方法 public EventObject(Object source) { if (source == null) throw new IllegalArgumentException("null source"); this.source = source; } //Get public Object getSource() { return source; }}
不难理解,Event核心在于对于资源的暴露。在EventObject对应的核心资源是发布这个事件的对象,因此我们看到实际是对发布对象的持有 。
进一步考虑,我们对于Tomcat的Event需求是什么?回到最初的问题,我们主要需要对Tomcat进行管理,Tomcat对于容器运行阶段做了一个抽象叫做Lifecycle(生命周期)。生命周期其实就是对于常用执行状态的抽象,下一节会给大家介绍。因此我们对于Tomcat生命周期LifecycleEvent设计如下
public final class LifecycleEvent extends EventObject { private final Lifecycle lifecycle; //生命周期具体阶段参数 private final String type; //可扩展资源 private final Object data; public LifecycleEvent(Object source, Lifecycle lifecycle, String type) { this(lifecycle, type, null); } public LifecycleEvent(Lifecycle lifecycle, String type, Object data) { super(lifecycle); this.lifecycle = lifecycle; this.type = type; this.data = data; } public Lifecycle getLifecycle() { return lifecycle; } public String getType() { return type; } public Object getData() { return data; }}
Lifecycle
上一节中,我们了解到Tomcat对于容器的运行状态做了抽象,抽象的内容被叫做Lifecycle
实际上Tomcat 对于容器运行状态抽象为六个状态,如示例所示。并且Lifecycle对象允许LifecycleListener,LifecycleListener下一节会说明。
对于需要对状态监测的对象,需要实现Lifecycle接口
public interface Lifecycle { String START_EVENT = "start"; String BEFORE_START_EVENT = "before_start"; String AFTER_START_EVENT = "after_start"; String STOP_EVENT = "stop"; String BEFORE_STOP_EVENT = "before_stop"; String AFTER_STOP_EVENT = "after_stop"; //增加LifecycleListener void addLifecycleListener(LifecycleListener listener); //获取全部LifecycleListener LifecycleListener[] findLifecycleListeners(); //移除对应LifecycleListener void removeLifecycleListener(LifecycleListener listener); //Lifecycle对象启动 void start() throws LifecycleException; //Lifecycle对象停止 void stop() throws LifecycleException;}
LifecycleListener
LifecycleListener是对Lifecycle的接口的抽象
核心方法lifecycleEvent通过LifecycleEvent进行容器声明周期管理
public interface LifecycleListener { void lifecycleEvent(LifecycleEvent event);}
在此示例SimpleContextLifecycleListener
public class SimpleContextLifecycleListener implements LifecycleListener { public void lifecycleEvent(LifecycleEvent event) { Lifecycle lifecycle = event.getLifecycle(); System.out.println("SimpleContextLifecycleListener's event " + event.getType().toString()); //声明周期控制 启动阶段 if (Lifecycle.START_EVENT.equals(event.getType())) { System.out.println("Starting context."); } //声明周期控制 停止阶段 else if (Lifecycle.STOP_EVENT.equals(event.getType())) { System.out.println("Stopping context."); } }}
实际上,基于Lifecycle的6个阶段,我们可以进行各个阶段的控制。
这三者的结构如下。
DEMO实现
由于每种Container都需要实现Lifecycle接口,对于这部分抽象对象LifecycleSupport
public final class LifecycleSupport { private Lifecycle lifecycle; private LifecycleListener listeners[] = new LifecycleListener[0]; public LifecycleSupport(Lifecycle lifecycle) { super(); this.lifecycle = lifecycle; } public void addLiffecycleListener(LifecycleListener listener) { synchronized (listeners) { LifecycleListener results[] = new LifecycleListener[listeners.length + 1]; for (int i = 0; i < listeners.length; i++) { results[i] = listeners[i]; } results[listeners.length] = listener; listeners = results; } } public LifecycleListener[] findLifecycleListeners() { return listeners; } public void fireLifecycleEvent(String type, Object data) { LifecycleEvent event = new LifecycleEvent(lifecycle, type, data); LifecycleListener interested[] = null; synchronized (listeners) { interested = (LifecycleListener[]) listeners.clone(); } for (int i = 0; i < interested.length; i++) { interested[i].lifecycleEvent(event); } } public void removeLifecycleListener(LifecycleListener listener) { synchronized (listeners) { int n = -1; for (int i = 0; i < listeners.length; i++) { if(listeners[i] == listener) { n = i; break; } } if(n < 0) return; LifecycleListener results[] = new LifecycleListener[listeners.length - 1]; int j = 0; for (int i = 0; i < listeners.length; i++) { if(i != n) { results[j++ ] = listeners[i]; } } listeners = results; } }}
这里只演示之前写的SimpleContext,其余容器类似
public class SimpleContext extends ContainerBase implements Context, Lifecycle { private LifecycleSupport lifecycleSupport = new LifecycleSupport(this); @Override public void addLifecycleListener(LifecycleListener listener) { lifecycleSupport.addLiffecycleListener(listener); } @Override public LifecycleListener[] findLifecycleListeners() { return lifecycleSupport.findLifecycleListeners(); } @Override public void removeLifecycleListener(LifecycleListener listener) { lifecycleSupport.removeLifecycleListener(listener); } @Override public void start() throws LifecycleException { lifecycleSupport.fireLifecycleEvent(Lifecycle.BEFORE_START_EVENT, null); lifecycleSupport.fireLifecycleEvent(Lifecycle.START_EVENT, null); Container[] lifeChildren = findChildren(); for (Container child : lifeChildren) { ((Lifecycle) child).start(); } lifecycleSupport.fireLifecycleEvent(Lifecycle.AFTER_START_EVENT, null); } @Override public void stop() throws LifecycleException { lifecycleSupport.fireLifecycleEvent(Lifecycle.BEFORE_START_EVENT, null); lifecycleSupport.fireLifecycleEvent(Lifecycle.STOP_EVENT, null); Container[] lifeChildren = findChildren(); for (Container child : lifeChildren) { ((Lifecycle) child).stop(); } lifecycleSupport.fireLifecycleEvent(Lifecycle.AFTER_STOP_EVENT, null); }}
- 【深入剖析Tomcat笔记】第六篇 Tomcat Lifecycle
- 【深入剖析Tomcat笔记】第二篇 ServerSocket模型
- 【深入剖析Tomcat笔记】第三篇 基本容器模型
- 【深入剖析Tomcat笔记】第四篇 默认连接器
- Tomcat Lifecycle
- 深入剖析Tomcat
- 深入剖析Tomcat-第一章
- 深入剖析tomcat第一章
- 读《深入剖析TOMCAT》
- 【深入剖析Tomcat笔记】第五篇 Tomcat Container 与 Pipelining Tasks
- How Tomcat works之第六章:Lifecycle生命周期
- 深入剖析Tomcat(How Tomcat Works)
- 【深入剖析Tomcat笔记】第一篇 基础知识储备
- 《深入剖析tomcat》读书笔记1
- 《深入剖析tomcat》读书笔记2
- 深入剖析Tomcat会话机制
- 深入剖析Tomcat读书笔记一
- 深入剖析Tomcat读书笔记二
- 后缀自动机习题集与归纳
- 2017多校第一场 Add More Zero(hdu6033)
- CentOS 6.5系统安装配置LAMP(Apache+PHP5+MySQL)服务器环境
- LeetCode 605. Can Place Flowers 自己的解法
- Redis 4.0.1集群搭建
- 【深入剖析Tomcat笔记】第六篇 Tomcat Lifecycle
- 南阳oj36 最长公共子序列 动态规划
- ajax基础
- Oracle基础(1)——用户
- foreach模板
- 全栈工程师之路-中级篇之小程序开发-第三章第四节点击查看大图,保存壁纸
- mysql的四种连接方式
- Android Studio 使用腾讯浏览服务(替换掉系统自带的WebView)
- 提取不重复的整数(去重)