一:java中的事件监听器
要实现java的监听器需要实现以下三个对象:
1事件对象:一般继承自java.util.EventObject,会作为参数用于监听处理方法中,要根据监听事件的需求自定义事件对象。类似mvc模式中的model实体类,主要用来存放事件处理需要的相关参数。
2事件源:事件源用于触发监听器方法,同时也可维护监听事件队列(启动、增加和删除监听器)。
3事件监听:以事件对象为参数,执行具体的事件方法。
三者关系如下:
具体例子如下:
//先定义事件对象
public
class
DemoEvent
extends
EventObject{
public
DemoEvent(
Object
source){
super(
source);
}
}
//定义一个Listener接口也即监听器
public
interface
DemoEventListener {
//事件发生后,如何处理
public
void
processEvent(
DemoEvent
demoEvent);//将事件对象作为参数传入方法
}
//定义Listener实现接口方法
public
class
FirstListener
implements
DemoEventListener{
public
void
processEvent(
DemoEvent
demoEvent){
System.
out.
println(
"FirstListener");
}
}
public
class
SecondListener
implements
DemoEventListener{
public
void
processEvent(
DemoEvent
demoEvent){
System.
out.
println(
"SecondListener");
}
}
//定义事件源
public
class
DemoEventSource{
private
List
<
DemoEventListener
>
listeners
=
new
ArrayList
<
DemoEventListener
>();//维护监听器数组
public
DemoEventListener(){
}
public
void
addListener(
DemoEventListener
demoEventListener){
listeners.
add(
demoEventListener);
}
public
void
notifyEvent(){
for(
DemoEventListener
demoEventListener :
listeners){//遍历监听器数组,并调用每一个监听器的方法
DemoEvent
demoEvent
=
new
DemoEvent();
demoEventListener.
processEvent(
demoEvent);
}
}
}
//测试类
public
class
Demo {
/**
*
@param
args
*/
public
static
void
main(
String[]
args) {
// TODO Auto-generated method stub
//定义事件源
DemoEventSource
demoEventSource
=
new
DemoEventSource();
//定义并向事件源中注册事件监听器
FirstListener
firstListener
=
new
FirstListener();
DemoEventSource.
addListener(
firstListener);
//定义并向事件源中注册事件监听器
SecondListener
secondListener
=
new
SecondListener();
DemoEventSource.
addListener(
secondListener);
//事件通知
DemoEventSource.
notifyDemoEvent();
}
}
二:tomcat中的生命周期
tomcat中当启动一个组件时往往也需要启动一系列的相关组件,即每个组件都有自己的生命周期。tomcat就利用上述的监听器机制实现了对组件生命周期的管理。
首先,事件对象的定义如下:
import java.util.EventObject;
/**
* General event for notifying listeners of significant changes on a component
* that implements the Lifecycle interface. In particular, this will be useful
* on Containers, where these events replace the ContextInterceptor concept in
* Tomcat 3.x.
*
* @author Craig R. McClanahan
* @version $Revision: 1.3 $ $Date: 2001/07/22 20:13:30 $
*/
public final class LifecycleEvent
extends EventObject {
// ----------------------------------------------------------- Constructors
/**
* Construct a new LifecycleEvent with the specified parameters.
*
* @param lifecycle Component on which this event occurred
* @param type Event type (required)
*/
public LifecycleEvent(Lifecycle lifecycle, String type) {
this(lifecycle, type, null);
}
/**
* Construct a new LifecycleEvent with the specified parameters.
*
* @param lifecycle Component on which this event occurred
* @param type Event type (required)
* @param data Event data (if any)
*/
public LifecycleEvent(Lifecycle lifecycle, String type, Object data) {
super(lifecycle);
this.lifecycle = lifecycle;
this.type = type;
this.data = data;
}
// ----------------------------------------------------- Instance Variables
/**
* The event data associated with this event.
*/
private Object data = null;
/**
* The Lifecycle on which this event occurred.
*/
private Lifecycle lifecycle = null;
/**
* The event type this instance represents.
*/
private String type = null;
// ------------------------------------------------------------- Properties
/**
* Return the event data of this event.
*/
public Object getData() {
return (this.data);
}
/**
* Return the Lifecycle on which this event occurred.
*/
public Lifecycle getLifecycle() {
return (this.lifecycle);
}
/**
* Return the event type of this event.
*/
public String getType() {
return (this.type);
}
}
这里只是简单的定义了data、lifecycle和type三个成员变量。
事件源的主要代码如下:
public final class LifecycleSupport {
/**
* The source component for lifecycle events that we will fire.
*/
private Lifecycle lifecycle = null;
/**
* The set of registered LifecycleListeners for event notifications.
*/
private LifecycleListener listeners[] = new LifecycleListener[0];
/**
* 触发某个事件
* Notify all lifecycle event listeners that a particular event has
* occurred for this Container. The default implementation performs
* this notification synchronously using the calling thread.
*
* @param type Event type
* @param data Event data
*/
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);//调用实现lifecycle接口的类中的事件运行方法
}
}
这里忽略构造函数以及对listeners[]的相关增删操作,fireLifecycleEvent通过参数生成事件对象并传给监听器处理。
监听器代码如下:
public class SimpleContextLifecycleListener implements LifecycleListener {
public void lifecycleEvent(LifecycleEvent event) {
Lifecycle lifecycle = event.getLifecycle();//从事件对象中取得lifecycle中的值
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.");
}
}
}
这样一个监听器就完成了,怎么使用呢?直接调用定义一个事件源对象protected LifecycleSupport lifecycle = new LifecycleSupport();然后通过调用lifecycle.fireLifecycleEvent(...,...);就可以运行监听器事件了。