标签:
java事件机制包括三个部分:事件、事件监听器、事件源。
事件:一般继承自java.util.EventObject类,封装了事件源对象,事件类型及跟事件相关的信息。
事件监听器:实现java.util.EventListener接口,注册在事件源上,当事件源的属性或状态改变时,取得相应的监听器调用其内部的回调方法。
事件源:事件发生的地方,由于事件源的某项属性或状态发生了改变(比如BUTTON被单击、TEXTBOX的值发生改变等等)导致某项事件发生。
//事件监听器好比一个间谍,要获取情报需要把她放到敌方阵营,当敌方有任何行动,就放一只鸽子通知友军或者秘密做一些事情
在之前的 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 {
-
-
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();
-
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
-
{
-
.............
-
-
-
-
private LifecycleSupport lifecycle = new LifecycleSupport(this);//this就是事件源
-
.............
-
-
-
-
-
protected Connector connectors[] = new Connector[0];
-
-
public void start() throws LifecycleException {
-
-
if (log.isInfoEnabled() && started) {
-
log.info(sm.getString("standardService.start.started"));
-
}
-
-
if( ! initialized )
-
init();
-
-
-
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT, null);//BEFORE_START_EVENT事件类型,监听器一般需要这个两个东西,事件源和事件类型。fire就是运行监听器的方法。
-
if(log.isInfoEnabled())
-
log.info(sm.getString("standardService.start.name", this.name));
-
-
lifecycle.fireLifecycleEvent(START_EVENT, null); <<<<(1)
-
started = true;
-
-
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();
-
}
-
}
-
-
-
synchronized (connectors) {
-
for (int i = 0; i < connectors.length; i++) {
-
if (connectors[i] instanceof Lifecycle)
-
((Lifecycle) connectors[i]).start();
-
}
-
}
-
-
-
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();
-
}
-
-
-
if( lifecycle instanceof Service ) {
-
try {
-
-
MBeanFactory factory = new MBeanFactory();
-
createMBeans(factory);
-
createMBeans((Service)lifecycle);
-
} catch( Exception ex ) {
-
log.error("Create mbean factory");
-
}
-
}
-
-
-
-
-
-
-
-
-
-
} 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);
-
-
}
-
-
-
-
-
}
-
-
if ((Context.RELOAD_EVENT.equals(event.getType()))
-
|| (Lifecycle.START_EVENT.equals(event.getType()))) {
-
-
-
-
-
if (lifecycle instanceof StandardContext) {
-
-
-
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内部的启动流程, 通过观察者模式与监听器模式来作处理, 组件启动方面,在启动上级组件的同时,先启动下一级组件, (当然,在父组件内部,需要包含它所有子组件引用的一个集合).
推荐书籍:how tomcat works.
Tomcat生命周期
标签:
原文地址:http://blog.csdn.net/u013782203/article/details/51297104