- 浏览: 58958 次
- 性别:
- 来自: 上海
最新评论
-
hesai_vip:
写的很不错! 果断收藏!
使用Open Flash Chart(OFC)制作图表(Struts2处理) -
EvanWei:
不知道你最后选了哪一个公司,我最近也在应聘Rovi
两个offer:rovi和凯捷中国,不知道如何选择
Servlet规范中定义了一个Servlet的生命周期, Tomcat使用事件方式管理Servlet的生命周期。 Tomcat定义了一个Lifecycle接口统一管理在容器内发生的所有事件。
Lifecycle接定义了两个方法start, stop来完成创建,初始化和结束的生命周期管理。
Lifecycle接口一共定义了九种事件类型。 所有容器内处理Servlet的类都继承该接口, 如StandarServer, StandarPipeline,ContainerBase以及各种Valve。
本文主要分析Tomcat中声明周期管理的设计和实现。
Author: Benewu(at)gmail.com
一,设计: Tomcat使用了组合(Composite)和观察者(Observer)模式。
设计核心是: Lifecycle, LifecycleListener, LifecycleEvent和LifecycleSupport
Lifecycle组合了LifecycleSupport,
1. 注册事件: Lifecycle中定义的addLifecycleListener实际是使用LifecycleSupport的addLifecycleListener。
2. 通知监听者: 当Lifecycle中发生动作尤其是start和stop时会调用LifecycleSupport的fireLifecycleEvent。 这个时候LifecycleSupport的fireLifecycleEvent会根据传入的事件类型,生成LifecycleEvent事件源并且遍历通知所有注册在里面的监听(LifecycleListener)的lifecycleEvent方法.
3. 监听者响应: 监听(LifecycleListener)会根据不同的事件类型做不同的操作。
二, 实现:
以JasperListener(初始化JSP编译引擎)监听在StandarServer的注册,通知和响应为例。
1. 注册事件: Tomcat允许用户自定义监听和加入,可以在serer.xml中灵活的配置。
- <Server port="8005" shutdown="SHUTDOWN">
- ... ...
- <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html -->
- <Listener className="org.apache.catalina.core.JasperListener" />
- ... ...
- </Server>
<Server port="8005" shutdown="SHUTDOWN"> ... ... <!--Initialize Jasper prior to webapps are loaded. Documentation at /docs/jasper-howto.html --> <Listener className="org.apache.catalina.core.JasperListener" /> ... ... </Server>
StandardServer继承Lifecycle接口, 有注册监听的方法。
StandardServer中注册监听的代码片断:
org.apache.catalina.core.StandardServer
- public final class StandardServer
- implements Lifecycle, Server, MBeanRegistration
- {
- ... ...
- // 组合模式
- private LifecycleSupport lifecycle = new LifecycleSupport(this);
- ... ...
- // 将监听加入到模块中
- public void addLifecycleListener(LifecycleListener listener) {
- lifecycle.addLifecycleListener(listener);
- }
- ... ...
- }
public final class StandardServer implements Lifecycle, Server, MBeanRegistration { ... ... // 组合模式 private LifecycleSupport lifecycle = new LifecycleSupport(this); ... ... // 将监听加入到模块中 public void addLifecycleListener(LifecycleListener listener) { lifecycle.addLifecycleListener(listener); } ... ... }
org.apache.catalina.util.LifecycleSupport 中addLifecycleListener方法完成注册监听的具体实现:
- public final class LifecycleSupport {
- ... ...
- private LifecycleListener listeners[] = new LifecycleListener[0];
- ... ...
- public void addLifecycleListener(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 final class LifecycleSupport { ... ... private LifecycleListener listeners[] = new LifecycleListener[0]; ... ... public void addLifecycleListener(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; } } ... ... }
Tomcat在启动的时候会将xml中配置的内容加载进去,(见《Tomcat中xml的解析器Digester》), 完成监听注册。
2. 通知监听者。
StandardServer在自身初始化的时候通知所有监听有初始化事件发生。
- public void initialize()
- throws LifecycleException
- {
- if (initialized) {
- log.info(sm.getString("standardServer.initialize.initialized"));
- return;
- }
- lifecycle.fireLifecycleEvent(INIT_EVENT, null);
- initialized = true;
- ... ...
- }
public void initialize() throws LifecycleException { if (initialized) { log.info(sm.getString("standardServer.initialize.initialized")); return; } lifecycle.fireLifecycleEvent(INIT_EVENT, null); initialized = true; ... ... }
LifecycleSupport实现具体动作, 生成事件源并通知所有监听
- public void fireLifecycleEvent(String type, Object data) {
- LifecycleEvent event = new LifecycleEvent(lifecycle, type, data);
- LifecycleListener interested[] = listeners;
- for (int i = 0; i < interested.length; i++)
- interested[i].lifecycleEvent(event);
- }
public void fireLifecycleEvent(String type, Object data) { LifecycleEvent event = new LifecycleEvent(lifecycle, type, data); LifecycleListener interested[] = listeners; for (int i = 0; i < interested.length; i++) interested[i].lifecycleEvent(event); }
3. 监听者响应
当LifecycleListener被调用lifecycleEvent方法, 会分析事件的类型, 根据类型做不同的响应或者不响应。
org.apache.catalina.core.JasperListener被注册在StandardServer,当StandardServer通知事件的时候, 它也会被调用。
调用到底方法是: lifecycleEvent
- public class JasperListener
- implements LifecycleListener {
- ... ...
- public void lifecycleEvent(LifecycleEvent event) {
- // 判断事件类型, 根据类型作出响应
- if (Lifecycle.INIT_EVENT.equals(event.getType())) {
- try {
- // Set JSP factory
- Class.forName("org.apache.jasper.compiler.JspRuntimeContext",
- true,
- this.getClass().getClassLoader());
- } catch (Throwable t) {
- // Should not occur, obviously
- log.warn("Couldn't initialize Jasper", t);
- }
- // Another possibility is to do directly:
- // JspFactory.setDefaultFactory(new JspFactoryImpl());
- }
- }
- ... ...
- }
public class JasperListener implements LifecycleListener { ... ... public void lifecycleEvent(LifecycleEvent event) { // 判断事件类型, 根据类型作出响应 if (Lifecycle.INIT_EVENT.equals(event.getType())) { try { // Set JSP factory Class.forName("org.apache.jasper.compiler.JspRuntimeContext", true, this.getClass().getClassLoader()); } catch (Throwable t) { // Should not occur, obviously log.warn("Couldn't initialize Jasper", t); } // Another possibility is to do directly: // JspFactory.setDefaultFactory(new JspFactoryImpl()); } } ... ... }
至此, Tomcat的生命周期管理分析就完成了。 可以看出Tomcat的生命周期管理设计的非常灵活和简单, 用户可以自如的加入不同监听到各个环节。
但也看出这个设计也有一些缺点, 比如每个监听都会被通知一遍,然后自己去判断事件类型。 如果容器发生的事件多而且监听也多, 会造成很多不必要的损耗。当然Tomcat的这个问题不是很大, 因为Tomcat发生的事件不多而且监听也不是很多。
参考:
1 Java Servlet概述
http://tech.ccidnet.com/art/1077/20041123/180515_1.html
2 Tomcat 6官方文档
http://tomcat.apache.org/tomcat-6.0-doc/index.html
发表评论
-
更深入的TOMCAT中文乱码解决之道,包括GET/POST(转)
2011-06-23 10:45 1605在tomcat5中发现了以前处 ... -
一些软件设计的原则
2011-06-20 15:20 908摘录自:http://coolshell.cn/article ... -
Jboss4集群配置
2011-06-08 17:49 35211.前言 2006年,Jboss公司被 ... -
ORACLE索引介绍与高性能SQL优化
2011-06-08 15:52 1023什么是索引 索引是建立在表的一列或多个列上的辅助对象,目 ... -
说说大型高并发高负载网站的系统架构(from tianya)
2011-06-07 15:03 913说说大型高并发高负载 ... -
dao对象不能使用注解@Repository实例化的情形之一
2011-06-03 17:47 15764项目中定义一个dao对象,继承了 JdbcDaoSupport ... -
SQL Server 索引结构及其使用(四)
2011-06-01 23:04 776聚集索引的重要性和如 ... -
SQL Server 索引结构及其使用(三)
2011-06-01 23:04 751实现小数据量和海量数据的通用分页显示存储过程 建立一个 W ... -
SQL Server 索引结构及其使用(二)
2011-06-01 23:03 863改善SQL语句 很多人 ... -
SQL Server 索引结构及其使用1
2011-06-01 22:59 852一、深入浅出理解索引结构 实际上,您可以把索引理解为一种特 ... -
如何使用Spring来管理Struts中的Action
2011-03-25 20:31 773当指定struts.objectFactory为spring时 ... -
eclipse无法启动JBoss5.1.0的解决小办法
2011-03-07 15:00 2024最近看看JBoss,发现早已有了新版本,好久没有关注了,于是下 ... -
log4j配置详解1
2010-12-17 15:15 776>>>>1. 概述Log4j ... -
Java日志系统框架的设计与实现
2010-12-17 11:15 1365在Java 领域,存在大量的日志组件,open-open收录了 ... -
胜负彩10001期欧洲四大博彩公司最新赔率
2010-09-20 13:37 24胜负彩对阵 威廉希尔 Interwetten 立博l ... -
明明白白Unsupported major.minor version 49.0的错误
2010-08-05 14:33 518转载自:http://www.blogjava.net/Unm ... -
一位系统分析师的工作经验总结
2010-07-20 15:39 1553谈到项目的需求分析,几乎每个软件开发人员 ... -
Tomcat6的结构
2010-05-17 17:28 1654本文分为三部分,分别为: Tomcat文件系统 Tom ... -
计算机端口管理
2010-05-12 11:03 923在运行中输入cmd,进入命令行,然后输入netstat -an ... -
Debug Tomcat时发生java.library.path错误的解决方法
2010-05-12 10:22 986Tomcat, library, java, path, 解 ...
相关推荐
在描述中提到的InstanceSupport.edx文件可能是一个教学资源,可能包含了关于Tomcat生命周期和事件管理的详细讲解和实例。通常,这种类型的文件可能是教育平台如EdX上的课程资料,用于辅助学习者理解相关概念。 了解...
了解Tomcat的架构,从Connector和Container这两个核心组件开始,理解它们的协同工作方式,以及Tomcat如何通过模块化的设计来管理服务组件的生命周期,对于深入使用和定制Tomcat是非常重要的。同时,观察和学习Tomcat...
Tomcat 系统架构与设计模式,第 1 部分:工作原理 本文将从 Tomcat 系统架构与设计模式的角度,...在下一部分中,我们将继续探讨 Tomcat 的工作原理,包括请求处理、Servlet 生命周期管理和生命周期事件处理等方面。
组件的生命周期管理 用Lifecycle管理启动、停止、关闭 Lifecycle接口预览 几个核心方法 Server中的init方法示例 为啥StandardServer没有init方法 LifecycleBase中的init与initInternal方法 为什么这么设计...
Lifecycle接口的引入是Tomcat设计中的一个重要决策,它提供了一种统一的方式来管理组件的生命周期,体现了设计模式中的一致性和可扩展性原则。 Tomcat的生命周期是由Server组件控制的,Server相当于整个Tomcat的...
6. **Lifecycle Interfaces**: Tomcat API包含一系列生命周期接口,如Lifecycle、LifecycleListener、LifecycleState等,用于管理组件的创建、启动、停止和销毁过程。开发者可以通过实现这些接口,监控和干预Tomcat...
2. **生命周期管理**:Tomcat中的`Lifecycle`接口和`LifecycleListener`类是管理组件生命周期的关键。通过观察各个组件如何遵循这个生命周期模型启动、停止和销毁,我们可以学习到服务的正确启动和关闭过程。 3. **...
- **生命周期管理**:Tomcat使用接口`Lifecycle`和`LifecycleListener`来管理组件的生命周期事件,如启动、停止、暂停和恢复。 - **部署与配置**:Tomcat的`server.xml`配置文件定义了服务器的全局设置,而`web.xml...
2. **btm-tomcat55-lifecycle-2.1.4**:这个jar包是专门为Tomcat5.5定制的BTM生命周期模块,它允许BTM与Tomcat的启动和停止过程无缝集成,确保在Tomcat启动时自动配置事务管理器,并在停止时清理资源。 3. **H2 ...
Tomcat 中的 Lifecycle 模式主要用于控制组件的生命周期。Lifecycle 模式可以使得组件的生命周期更加可控和灵活。 三、Tomcat 的总体结构 Tomcat 的总体结构图可以看出,Tomcat 的核心组件是 Connector 和 ...
4. **生命周期管理(Lifecycle Management)**:Tomcat中的每个组件都有自己的生命周期,包括初始化、启动、停止和销毁等阶段。通过Lifecycle接口,Tomcat能够监听这些事件,并在适当的时候执行相应的操作。 三、...
`Servlet_LifeCycle_Demo`这个项目旨在深入理解Servlet的生命周期及其管理方法。在这个示例中,我们将探讨Servlet如何启动、初始化、处理请求、服务多个请求、以及最终销毁。 首先,Servlet的生命周期分为四个主要...
3. 生命周期管理器(Lifecycle):生命周期管理器是Tomcat中的一个接口,它定义了组件生命周期的管理方法,如初始化、启动、停止和销毁等。所有Tomcat组件都遵循这一生命周期,使得整个服务器可以在启动时初始化所有...
4. **Lifecycle**:在Tomcat中,每个组件都有一个生命周期,包括初始化、启动、停止和销毁等阶段。源码中关于生命周期的管理可以帮助我们理解组件如何正确地启动和关闭。 5. **Logging**:Tomcat使用内置的日志系统...
Service接口没有直接控制组件的生命周期,而是依赖于Lifecycle接口来实现,这是职责链模式的应用,使得组件的生命周期管理更加灵活和独立。 总的来说,理解Tomcat的架构对于优化性能、调试问题和扩展功能至关重要。...
4. **生命周期管理**:Tomcat通过`Lifecycle`接口和`LifeCycleListener`机制来管理Servlet的生命周期,包括装载、初始化、启动、停止和卸载等阶段。 5. **JSP编译**:Jasper会监控JSP文件的改动,自动重新编译。JSP...
生命周期(Lifecycle)是Tomcat设计中的一个重要概念,它通过`Lifecycle`接口统一管理各个组件的启动、停止和关闭操作。此外,`MBeanRegistration`接口用于实现JMX(Java Management Extensions)功能,使得我们可以...
4. **Wrapper**:代表单个Servlet的包装器,封装了Servlet的生命周期管理。 #### 四、Tomcat的版本 Tomcat的版本迭代反映了其不断发展的历程,不同版本之间可能存在显著的功能差异。例如,Tomcat 4与5版本相比,在...