浏览 4230 次
锁定老帖子 主题:Tomcat的生命周期管理
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2007-12-02
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> 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); } ... ... } 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; } } ... ... } 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; ... ... } 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); } 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()); } } ... ... } 至此, 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 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |