- 浏览: 205572 次
- 性别:
- 来自: 杭州
文章分类
最新评论
-
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 1794tomcat在启动的时候,会去加载并解析server.xml ... -
tomcat init中加载哪些类?
2010-09-19 00:10 1392tomcat初始化过程中,会加载一些安全的类。 那到底会 ... -
tomcat init思维图
2010-09-18 00:23 1754很久没有研究tomcat啦,晚上把代码打开重新研究了一下,看了 ... -
Tomcat-整体架构
2010-05-31 01:53 2015似乎JE直接粘贴Word的文章会出现排版问题, 算了, 直接 ... -
tomcat解析之简单web服务器(图)
2010-02-04 01:08 3111之前有javaeyer推荐了一本书《how tomca ... -
Tomcat解析之初始化类加载器(截图)
2010-01-30 23:16 2376之前有写过关于tomcat中常用的一些类结构的文章。 ... -
解析Tomcat之HttpServlet(截图记录)
2010-01-01 22:10 3785新年之际,正好趁 ...
相关推荐
本文将深入探讨Tomcat的生命周期管理和事件管理,这两个概念是理解和优化Tomcat应用程序性能的关键。 首先,让我们关注Tomcat的生命周期。每个在Tomcat中部署的应用程序都有一个特定的生命周期,它由一系列的阶段...
Tomcat的架构设计中使用了多个设计模式,例如上述生命周期管理的实现运用了状态模式,事件监听机制则运用了观察者模式。这些设计模式的使用大大增强了Tomcat的扩展性、灵活性和可维护性。 总结来说,Tomcat的架构...
使用JAVA语言写的项目管理软件,可以跟踪任务和bug的进度,实现对任务和bug全生命周期管理。 这个项目是很早之前开发的(大约在2008年前后),所以使用的技术是传统的JSP/Servlet+JDBC方式。虽然技术比较老了,但是...
Servlet生命周期是Java Web开发中一个关键的概念,它描述了Servlet从创建到销毁的整个过程,这个过程由Servlet容器(如Tomcat)进行管理。Servlet生命周期主要分为三个阶段:初始化阶段、运行阶段和销毁阶段。 1. ...
3. **生命周期管理**:每个Tomcat组件都有自己的生命周期,包括初始化、启动、停止和销毁。源码中,这些生命周期方法的实现有助于理解Tomcat的内部工作流程。 4. **部署与加载**:Tomcat可以自动或手动部署Web应用...
Servlet生命周期是Java Web开发中的核心概念,它涵盖了Servlet从创建到销毁的整个过程,主要分为初始化...理解并掌握Servlet的生命周期对于优化性能和管理资源至关重要,尤其是在处理高并发和长时间运行的Web应用中。
3. **Servlet生命周期**:Servlet在Tomcat中的生命周期包括加载、初始化、服务、销毁四个阶段。Tomcat通过Servlet容器管理Servlet实例,确保其正确地创建、初始化和销毁。 4. **请求处理**:当一个HTTP请求到达时,...
3. **生命周期管理**:Tomcat按照一定的生命周期管理Servlet,包括加载、初始化、服务、销毁等阶段。每个Servlet实例都有自己的生命周期,Tomcat会根据需要创建和销毁它们。 4. **连接器(Connector)**:Tomcat...
6. **Lifecycle Interfaces**: Tomcat API包含一系列生命周期接口,如Lifecycle、LifecycleListener、LifecycleState等,用于管理组件的创建、启动、停止和销毁过程。开发者可以通过实现这些接口,监控和干预Tomcat...
Tomcat 系统架构与设计模式,第 1 部分:工作原理 本文将从 Tomcat 系统架构与设计模式的角度,...在下一部分中,我们将继续探讨 Tomcat 的工作原理,包括请求处理、Servlet 生命周期管理和生命周期事件处理等方面。
StandardService类除了实现Service接口外,还实现了Lifecycle接口,这使得StandardService可以对下属组件进行生命周期管理,包括启动、停止、重启等。Lifecycle接口的引入是Tomcat设计中的一个重要决策,它提供了一...
生命周期管理: Servlet容器负责管理Servlet的生命周期,包括初始化、服务处理和销毁。 当Servlet容器启动时,它会加载并初始化配置中指定的Servlet类。在Servlet的生命周期中,容器负责调用相应的生命周期方法,...
### Servlet 生命周期详解 #### 一、概述 ...了解 Servlet 的生命周期对于更好地控制和优化 Web 应用程序至关重要...通过深入了解 Servlet 的生命周期,开发者可以更有效地管理和优化 Web 应用程序,提高其性能和稳定性。
### Servlet执行过程与生命周期详解 在探讨Servlet的执行...理解Servlet的执行过程与生命周期对Java Web开发至关重要,它不仅帮助开发者设计出更高效、更健壮的Web应用,还为解决常见的Web开发问题提供了理论基础。
在实际开发中,理解Servlet的生命周期对于优化性能和管理资源至关重要。例如,可以通过控制Servlet的实例化次数来减少内存消耗,或者在`init()`方法中初始化一次性的资源,在`destroy()`方法中及时释放,以确保...
Servlet容器负责创建Servlet的实例,管理其生命周期,并处理来自客户端的请求。 3. **.war文件**:WAR(Web Application Archive)文件是Java Web应用程序的标准打包格式,包含了所有必要的资源,如HTML、CSS、...
1. **Catalina**:这是Tomcat的核心组件,负责Servlet容器的主要功能,如容器管理、生命周期管理和请求处理。Catalina包含Context、Host和Engine等层次结构,它们分别对应于Web应用、虚拟主机和整个服务器。 2. **...
4. **生命周期管理**:Tomcat管理Web应用程序的生命周期,包括加载、初始化、服务、停止和卸载等阶段。 5. **安全性**:Tomcat支持各种安全机制,如SSL/TLS加密、基本认证、digest认证和Form认证等。 6. **配置...