本文接下来描述servlet容器是怎样管理其相关组件的生命周期的,首先本人描述一下事件监听模式,也可以称为观察者模式,该模式分为以下角色
即抽象主题角色 具体主题角色 抽象观察者角色及具体观察者角色,通常在主题角色里面维持一个观察者角色的聚集,并定义了对观察者角色的添加和删除方法;在主题角色事件发生时,通过迭代向这些观察者角色发布事件。
在tomcat容器中,管理其相关组件的生命周期即是基于事件监听模式实现的,相关接口和类为org.apache.catalina.Lifecycle接口、org.apache.catalina.LifecycleListener接口、org.apache.catalina.LifecycleEvent类
org.apache.catalina.Lifecycle接口定义如下
public
interface
Lifecycle {
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
void
addLifecycleListener(LifecycleListener listener);
public
LifecycleListener[] findLifecycleListeners();
public
void
removeLifecycleListener(LifecycleListener listener);
public
void
start()
throws
LifecycleException;
public
void
stop()
throws
LifecycleException;
}
上面的六个静态字符串代表六种类型的事件,接着的三个方法addLifecycleListener()、 findLifecycleListeners()、removeLifecycleListener()为与事件监听器相关的,最后的两个方法start()和stop()为启动与关闭操作,组件必须提供这两种方法的实现,供其父组件调用。
org.apache.catalina.LifecycleEvent类用于传递事件及携带事件数据
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);
}
}
org.apache.catalina.LifecycleListener为监听器接口
public
interface
LifecycleListener {
/**
* Acknowledge the occurrence of the specified event.
*
*
@param
event LifecycleEvent that has occurred
*/
public
void
lifecycleEvent(LifecycleEvent event);
}
通常实现了Lifecycle接口并且对某个事件注册了监听器的组件必须提供 Lifecycle接口中三个与监听器相关方法(分别为addLifecycleListener()、 findLifecycleListeners()、removeLifecycleListener())的实现,然后该组件需要将所有注册的监听器存储到数组、ArrayList或者其他类似的对象中;tomcat容器提供了一个工具类org.apache.catalina.util.LifecycleSupport来帮助组件管理监听器,并触发相应的生命周期事件。
public
final
class
LifecycleSupport {
public
LifecycleSupport(Lifecycle lifecycle) {
super
();
this
.lifecycle =
lifecycle;
}
private
Lifecycle lifecycle =
null
;
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
LifecycleListener[] findLifecycleListeners() {
return
listeners;
}
public
void
fireLifecycleEvent(String type, Object data) {
LifecycleEvent event
=
new
LifecycleEvent(lifecycle, type, data);
LifecycleListener interested[]
=
null
;
synchronized
(listeners) {
interested
=
(LifecycleListener[]) listeners.clone();
}
for
(
int
i = 0; i < interested.length; i++
)
interested[i].lifecycleEvent(event);
}
public
void
removeLifecycleListener(LifecycleListener listener) {
synchronized
(listeners) {
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;
}
}
}
下面我们来看Context容器(SimpleContext实例)是怎么实现生命周期管理及触发监听器事件的,关键代码如下
public
class
SimpleContext
implements
Context, Pipeline, Lifecycle {
protected
LifecycleSupport lifecycle =
new
LifecycleSupport(
this
);
//
implementation of the Lifecycle interface's methods
public
void
addLifecycleListener(LifecycleListener listener) {
lifecycle.addLifecycleListener(listener);
}
public
LifecycleListener[] findLifecycleListeners() {
return
null
;
}
public
void
removeLifecycleListener(LifecycleListener listener) {
lifecycle.removeLifecycleListener(listener);
}
public
synchronized
void
start()
throws
LifecycleException {
if
(started)
throw
new
LifecycleException("SimpleContext has already started"
);
//
Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT,
null
);
started
=
true
;
try
{
//
Start our subordinate components, if any
if
((loader !=
null
) && (loader
instanceof
Lifecycle))
((Lifecycle) loader).start();
//
Start our child containers, if any
Container children[] =
findChildren();
for
(
int
i = 0; i < children.length; i++
) {
if
(children[i]
instanceof
Lifecycle)
((Lifecycle) children[i]).start();
}
//
Start the Valves in our pipeline (including the basic),
//
if any
if
(pipeline
instanceof
Lifecycle)
((Lifecycle) pipeline).start();
//
Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(START_EVENT,
null
);
}
catch
(Exception e) {
e.printStackTrace();
}
//
Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT,
null
);
}
public
void
stop()
throws
LifecycleException {
if
(!
started)
throw
new
LifecycleException("SimpleContext has not been started"
);
//
Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT,
null
);
lifecycle.fireLifecycleEvent(STOP_EVENT,
null
);
started
=
false
;
try
{
//
Stop the Valves in our pipeline (including the basic), if any
if
(pipeline
instanceof
Lifecycle) {
((Lifecycle) pipeline).stop();
}
//
Stop our child containers, if any
Container children[] =
findChildren();
for
(
int
i = 0; i < children.length; i++
) {
if
(children[i]
instanceof
Lifecycle)
((Lifecycle) children[i]).stop();
}
if
((loader !=
null
) && (loader
instanceof
Lifecycle)) {
((Lifecycle) loader).stop();
}
}
catch
(Exception e) {
e.printStackTrace();
}
//
Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT,
null
);
}
}
Context容器实例持有对LifecycleSupport lifecycle = new LifecycleSupport(this)的引用,与事件监听器相关方法均为操作该实例的相应方法
在其与生命周期相关方法start()和stop()方法里面,分别调用相关组件的生命周期方法,并采用LifecycleSupport lifecycle引用发布事件
一个简单的监听器实现如下:
public
class
SimpleContextLifecycleListener
implements
LifecycleListener {
public
void
lifecycleEvent(LifecycleEvent event) {
Lifecycle lifecycle
=
event.getLifecycle();
System.out.println(
"SimpleContextLifecycleListener's event " +
event.getType().toString());
if
(Lifecycle.START_EVENT.equals(event.getType())) {
System.out.println(
"Starting context."
);
}
else
if
(Lifecycle.STOP_EVENT.equals(event.getType())) {
System.out.println(
"Stopping context."
);
}
}
}
子容器wrapper实例(SimpleWrapper),同样实现了Lifecycle接口,其相关实现与Context容器类似
public
class
SimpleWrapper
implements
Wrapper, Pipeline, Lifecycle {
protected
LifecycleSupport lifecycle =
new
LifecycleSupport(
this
);
//
implementation of the Lifecycle interface's methods
public
void
addLifecycleListener(LifecycleListener listener) {
}
public
LifecycleListener[] findLifecycleListeners() {
return
null
;
}
public
void
removeLifecycleListener(LifecycleListener listener) {
}
public
synchronized
void
start()
throws
LifecycleException {
System.out.println(
"Starting Wrapper " +
name);
if
(started)
throw
new
LifecycleException("Wrapper already started"
);
//
Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_START_EVENT,
null
);
started
=
true
;
//
Start our subordinate components, if any
if
((loader !=
null
) && (loader
instanceof
Lifecycle))
((Lifecycle) loader).start();
//
Start the Valves in our pipeline (including the basic), if any
if
(pipeline
instanceof
Lifecycle)
((Lifecycle) pipeline).start();
//
Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(START_EVENT,
null
);
//
Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_START_EVENT,
null
);
}
public
void
stop()
throws
LifecycleException {
System.out.println(
"Stopping wrapper " +
name);
//
Shut down our servlet instance (if it has been initialized)
try
{
instance.destroy();
}
catch
(Throwable t) {
}
instance
=
null
;
if
(!
started)
throw
new
LifecycleException("Wrapper " + name + " not started"
);
//
Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(BEFORE_STOP_EVENT,
null
);
//
Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(STOP_EVENT,
null
);
started
=
false
;
//
Stop the Valves in our pipeline (including the basic), if any
if
(pipeline
instanceof
Lifecycle) {
((Lifecycle) pipeline).stop();
}
//
Stop our subordinate components, if any
if
((loader !=
null
) && (loader
instanceof
Lifecycle)) {
((Lifecycle) loader).stop();
}
//
Notify our interested LifecycleListeners
lifecycle.fireLifecycleEvent(AFTER_STOP_EVENT,
null
);
}
}
其他相关组件的相关实现不再赘述
---------------------------------------------------------------------------
本系列How Tomcat Works系本人原创
转载请注明出处 博客园 刺猬的温驯
本人邮箱: chenying998179 # 163.com ( #改为@ )

