- 浏览: 201935 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
harim:
思路十分不错,最近两家公司面试都问到了这个问题,我没有答出来, ...
缓存策略之LRU实现(基于双链表实现) -
javatozhang:
楼主真是良苦用心,很可惜我现在才对Tomcat感兴趣并有时间来 ...
tomcat init中加载哪些类? -
javatozhang:
diecui1202 写道可以看看goldendoc.org小 ...
tomcat init思维图 -
cherishLC:
非常感谢~表示自己没用过jquery,如果 jquery地址改 ...
最简单的jQuery折叠菜单 -
zhypengjw2012:
非常感谢!我今天就用到了!
jQuery插件--滑动条
在之前的 Tomcat 整体架构中可以看到 Tomcat 包含多个很多个组件 , 今天我们来看看, Tomcat 是如何管理这些组件的生命周期的。
我们知道,组件与组件之间,必须建立起相互的关系,才能做到同时启动与停止。 Tomcat 内部,使用一个观察者模式来组织这些组件之间的关系。
我们来看看, Tomcat 启动时,它会做哪些处理……
日志:
…… 2010-6-19 15:41:18 org.apache.catalina.core.StandardService start 信息 : Starting service Catalina 2010-6-19 15:41:18 org.apache.catalina.core.StandardEngine start 信息 : Starting Servlet Engine: Apache Tomcat/6.0.18 … 2010-6-19 15:41:19 org.apache.coyote.http11.Http11Protocol start 信息 : Starting Coyote HTTP/1.1 on http-8080 2010-6-19 15:41:19 org.apache.jk.common.ChannelSocket init 信息 : JK: ajp13 listening on /0.0.0.0:8009 2010-6-19 15:41:19 org.apache.jk.server.JkMain start 信息 : Jk running ID=0 time=0/182 config=null 2010-6-19 15:41:19 org.apache.catalina.startup.Catalina start 信息 : Server startup in 1706 ms
我们看到,它的启动顺序:
StandardService --> StandardEngine-->Http11Protocol-->JkMain-->Catalina
OK, 我们来看看在 Tomcat 内部的,他是如何做的
首先, Tomcat内部的生命周期的相关定义都在接口 Lifecycle 中,
package org.apache.catalina; public interface Lifecycle { public static final String INIT_EVENT = "init"; public static final String START_EVENT = "start"; public static final String BEFORE_START_EVENT = "before_start"; public static final String AFTER_START_EVENT = "after_start"; public static final String STOP_EVENT = "stop"; public static final String BEFORE_STOP_EVENT = "before_stop"; public static final String AFTER_STOP_EVENT = "after_stop"; public static final String DESTROY_EVENT = "destroy"; public static final String PERIODIC_EVENT = "periodic"; public void addLifecycleListener(LifecycleListener listener); public LifecycleListener[] findLifecycleListeners(); public void removeLifecycleListener(LifecycleListener listener); public void start() throws LifecycleException; public void stop() throws LifecycleException; }
另外生命周期的相关事件,定义在 LifecycleEvent 类中
package org.apache.catalina; import java.util.EventObject; public final class LifecycleEvent extends EventObject { // ----------------------------------------------------------- Constructors public LifecycleEvent(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; } private Object data = null; private Lifecycle lifecycle = null; private String type = null; public Object getData() { return (this.data); } public Lifecycle getLifecycle() { return (this.lifecycle); } public String getType() { return (this.type); } }
关于事件的监听,在接口LifecycleListener 中有定义
package org.apache.catalina; public interface LifecycleListener { public void lifecycleEvent(LifecycleEvent event); }
另外,这里还需要介绍一个特别的类:LifecycleSupport, 用于触发生命周期的相关事件.
package org.apache.catalina.util; import org.apache.catalina.Lifecycle; import org.apache.catalina.LifecycleEvent; import org.apache.catalina.LifecycleListener; public final class LifecycleSupport { public LifecycleSupport(Lifecycle lifecycle) { super(); this.lifecycle = lifecycle; } private Lifecycle lifecycle = null; private LifecycleListener listeners[] = new LifecycleListener[0]; private final Object listenersLock = new Object(); // Lock object for changes to listeners public void addLifecycleListener(LifecycleListener listener) { synchronized (listenersLock) { 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[] = listeners; for (int i = 0; i < interested.length; i++) interested[i].lifecycleEvent(event); } public void removeLifecycleListener(LifecycleListener listener) { synchronized (listenersLock) { 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; } } }
下面,我们来看看 StandardService 类的启动方法, 看它是如何启动的
在service真正启动时,他首先会触发一些启动前的事件,
然后启动它自己
接着,它会启动它关联的容器对象,
然后,将所有它的子组件—既连接器 全部都启动 ,下面是详细的代码/
public class StandardService implements Lifecycle, Service, MBeanRegistration { ............. /** * The lifecycle event support for this component. */ private LifecycleSupport lifecycle = new LifecycleSupport(this); ............. /** * The set of Connectors associated with this Service. 关联到这个Service的连接器对象. */ protected Connector connectors[] = new Connector[0]; public void start() throws LifecycleException { // Validate and update our current component state if (log.isInfoEnabled() && started) { log.info(sm.getString("standardService.start.started")); } if( ! initialized ) init(); // 触发启动之前的事件 lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null); if(log.isInfoEnabled()) log.info(sm.getString("standardService.start.name", this.name)); lifecycle.fireLifecycleEvent(START_EVENT, null); <<<<(1) started = true; // Start our defined Container first 首先启动关联的容器 if (container != null) { synchronized (container) { if (container instanceof Lifecycle) { ((Lifecycle) container).start(); } } } synchronized (executors) { for ( int i=0; i<executors.size(); i++ ) { executors.get(i).start(); } } // Start our defined Connectors second 再启动关联的连接器 synchronized (connectors) { for (int i = 0; i < connectors.length; i++) { if (connectors[i] instanceof Lifecycle) ((Lifecycle) connectors[i]).start(); } } // Notify our interested LifecycleListeners lifecycle.fireLifecycleEvent(AFTER_START_EVENT, null); }
代码(1)处,显示出,在Service正式启动之前,它还会出发启动前的事件,我们来看看,这个方法具体做些什么. 调用LifecycleSupport 类的 fireLifecycleEvent(START_EVENT, null);方法
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); }
而在内部,Service启动时,这里真正调用的是类 ServerLifecycleListener的方法:
package org.apache.catalina.mbeans; public class ServerLifecycleListener implements ContainerListener, LifecycleListener, PropertyChangeListener { public void lifecycleEvent(LifecycleEvent event) { Lifecycle lifecycle = event.getLifecycle(); if (Lifecycle.START_EVENT.equals(event.getType())) { if (lifecycle instanceof Server) { createMBeans(); } // We are embedded. if( lifecycle instanceof Service ) { try { //Service启动时,触发的事件 MBeanFactory factory = new MBeanFactory(); createMBeans(factory); createMBeans((Service)lifecycle); } catch( Exception ex ) { log.error("Create mbean factory"); } } /* // Ignore events from StandardContext objects to avoid // reregistering the context if (lifecycle instanceof StandardContext) return; createMBeans(); */ } else if (Lifecycle.AFTER_STOP_EVENT.equals(event.getType())) { try { if (lifecycle instanceof Server) { destroyMBeans((Server)lifecycle); } if (lifecycle instanceof Service) { destroyMBeans((Service)lifecycle); } } catch (MBeanException t) { Exception e = t.getTargetException(); if (e == null) { e = t; } log.error("destroyMBeans: MBeanException", e); } catch (Throwable t) { log.error("destroyMBeans: Throwable", t); } // FIXME: RMI adaptor should be stopped; however, this is // undocumented in MX4J, and reports exist in the MX4J bug DB that // this doesn't work } if ((Context.RELOAD_EVENT.equals(event.getType())) || (Lifecycle.START_EVENT.equals(event.getType()))) { // Give context a new handle to the MBean server if the // context has been reloaded since reloading causes the // context to lose its previous handle to the server if (lifecycle instanceof StandardContext) { // If the context is privileged, give a reference to it // in a servlet context attribute StandardContext context = (StandardContext)lifecycle; if (context.getPrivileged()) { context.getServletContext().setAttribute (Globals.MBEAN_REGISTRY_ATTR, MBeanUtils.createRegistry()); context.getServletContext().setAttribute (Globals.MBEAN_SERVER_ATTR, MBeanUtils.createServer()); } } } } }
这里简单介绍一下,Tomcat内部的启动流程, 通过观察者模式与监听器模式来作处理, 组件启动方面,在启动上级组件的同时,先启动下一级组件, (当然,在父组件内部,需要包含它所有子组件引用的一个集合).
发表评论
-
tomcat 启动解析server.xml 思维图
2011-09-28 01:26 1739tomcat在启动的时候,会去加载并解析server.xml ... -
tomcat init中加载哪些类?
2010-09-19 00:10 1340tomcat初始化过程中,会加载一些安全的类。 那到底会 ... -
tomcat init思维图
2010-09-18 00:23 1691很久没有研究tomcat啦,晚上把代码打开重新研究了一下,看了 ... -
Tomcat-整体架构
2010-05-31 01:53 1925似乎JE直接粘贴Word的文章会出现排版问题, 算了, 直接 ... -
tomcat解析之简单web服务器(图)
2010-02-04 01:08 3063之前有javaeyer推荐了一本书《how tomca ... -
Tomcat解析之初始化类加载器(截图)
2010-01-30 23:16 2335之前有写过关于tomcat中常用的一些类结构的文章。 ... -
解析Tomcat之HttpServlet(截图记录)
2010-01-01 22:10 3734新年之际,正好趁 ...
相关推荐
NULL 博文链接:https://yjhexy.iteye.com/blog/669427
使用JAVA语言写的项目管理软件,可以跟踪任务和bug的进度,实现对任务和bug全生命周期管理。 这个项目是很早之前开发的(大约在2008年前后),所以使用的技术是传统的JSP/Servlet+JDBC方式。虽然技术比较老了,但是...
组件的生命周期管理 用Lifecycle管理启动、停止、关闭 Lifecycle接口预览 几个核心方法 Server中的init方法示例 为啥StandardServer没有init方法 LifecycleBase中的init与initInternal方法 为什么这么设计...
在9.x系列的剩余生命周期内完全改变了: - 没有 可以添加以下类的公共接口以便 解决错误和/或添加新功能。没有现有的接口方法 已删除或更改,但可能已弃用。 - 没有 注意:随着Tomcat 9的成熟,以上列表将被添加到...
Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Dependency Management System),和用来运行定义在生命周期...
第6章 生命周期 第7章 日志记录器 第8章 载入器 第9章 session管理 第10章 安全性 第11章 standardwrapper 第12章 standardcontext类 第13章 host和engine 第14章 服务器组件和服务组件 第15章 digester库...
Tomcat 6.x的用户应该计划在Tomcat 6.x到达生命周期之前进行升级。 Apache Tomcat 5.x 的Apache Tomcat 5.x的是可以从档案下载。 的Apache Tomcat 5.5.X支持相同的Servlet和JSP规范版本的的Apache Tomcat 5.0.x中...
组件的生命周期方法由容器自动调用。 如何基于tomcat编写服务端动态应用? 基于tomcat编写JSP: JSP (Java Server Page) Java服务端页面生成技术 JSP的本质是一个Servlet类。 如何编写一个JSP? 1>创建...
详细的介绍了tomcat的组成结构、生命周期管理以及管道机制。
Servlet的生命周期由Web容器(如Tomcat)管理,包括加载、初始化、服务、销毁等阶段。 二、组件包 Java EE SDK: Java EE SDK提供了JavaWeb应用程序开发所需的所有API和库。 Tomcat: Tomcat二进制包,包含了Tomcat...
在上文Nginx+Tomcat关于Session的管理中简单介绍了如何使用redis来集中管理session,本文首先将介绍默认的管理器是如何管理Session的生命周期的,然后在此基础上对Redis集中式管理Session进行分析。 Tomcat Manager...
第六章生命周期 第七章日志记录器 第八章加载器 第九章会议管理 第十章应用程序 第十一章StandardWrapper 第十二章StandardContext 第十三章主机和引擎 第十四章服务器组件和服务组件 第十五章消化器库 第十六章关闭...
讲述Tomcat的工作原理 第1章 一个简单的Web服务器 ...第6章 生命周期(Lifecycle) 第7章 Logger 第8章 Loader 第9章 session管理 第10章 安全性 第11章 StandardWrapper 第12章 StandardContext类 ...
omcat是一个轻量级应用服务器,是支持运行Servlet/JSP应用程序的容器,运行在jvm上,绑定IP地址并监听...1)管理servlet应用的生命周期 (2)把客户端请求的url映射到对应的servlet (3)与Servlet程序合作处理HTTP请求
第6章 生命周期(Lifecycle) 43 6.1 概述 43 6.2 Lifecycle接口 43 6.3 LifecycleEvent类 44 6.4 LifecycleListener接口 44 6.5 LifecycleSupport类 44 6.6 应用程序 45 6.6.1 ex06.pyrmont.core.SimpleContext 45 ...
项目管理系统(PM):对项目全生命周期进行规划、跟踪、控制,确保项目按时、按质、按预算完成。 三、价值与优势 提高效率:自动化工作流程、标准化业务操作,显著减少人工干预,提升工作效率。 优化决策:实时...
第6章 生命周期(Lifecycle) 43 6.1 概述 43 6.2 Lifecycle接口 43 6.3 LifecycleEvent类 44 6.4 LifecycleListener接口 44 6.5 LifecycleSupport类 44 6.6 应用程序 45 6.6.1 ex06.pyrmont.core.SimpleContext 45 ...
并且采用了系统生命周期的结构化程序设计方法,从而将整个系统开发各阶段(系统分析、系统设计、系统实施)的基本活动贯穿起来。 所需开发环境: 开发语言:Java JDK版本:JDK1.8 服务器:tomcat7+ 数据库:mysql ...
并且采用了系统生命周期的结构化程序设计方法,从而将整个系统开发各阶段(系统分析、系统设计、系统实施)的基本活动贯穿起来。 所需开发环境: 开发语言:Java JDK版本:JDK1.8 服务器:tomcat7+ 数据库:mysql ...