监听器模式

文章目录
  1. 1. 监听器模式
  2. 2. jdk中监听器模式的实现
  3. 3. spring中监听器模式的实现
  4. 4. spring中监听器模式的使用
监听器模式

针对监听器模式,jdk提供了EventListener接口和EventObject类,分别定义事件监听器和事件对象。下面是通过扩展这两个接口实现一个简单的事件监听器模式。

/**
* @Author long
* @Date 2019/9/13 11:03
*/
public class App {
public static void main(String[] args) {
// 事件源
MyEventSource eventSource = new MyEventSource();
// 创建事件监听器->处理EventObject
StartEventListener startEventListener = new StartEventListener();
ClosedEventListener closedEventListener = new ClosedEventListener();
// 添加事件监听器
eventSource.addEventListener(startEventListener);
eventSource.addEventListener(closedEventListener);
// 创建事件对象
EventObject startEventObject = new EventObject("start");
EventObject closedEventObject = new EventObject("closed");
// 事件源->通知事件监听者来处理
eventSource.notifyListenerEvents(startEventObject);
eventSource.notifyListenerEvents(closedEventObject);
}
}

/**
* @Author long
* @Date 2019/9/13 11:00
* 扩展的监听器接口
*/
public interface MyEventListener extends EventListener {
/**
* 处理EventObject
* @param event
*/
void handleEvent(EventObject event);
}

/**
* @Author long
* @Date 2019/9/13 11:21
* 启动事件监听器
*/
public class StartEventListener implements MyEventListener {

@Override
public void handleEvent(EventObject event) {
Object source = event.getSource();
if (source.equals("start")) {
System.out.println("context has start!");
}
}
}

/**
* @Author long
* @Date 2019/9/13 11:24
* 关闭事件监听器
*/
public class ClosedEventListener implements MyEventListener {

@Override
public void handleEvent(EventObject event) {
Object source = event.getSource();
if (source.equals("closed")) {
System.out.println("context has closed!");
}
}
}

/**
* @Author long
* @Date 2019/9/13 11:03
* 事件源->添加 删除 通知
*/
public class MyEventSource {

/**
* 监听器列表
*/
private Vector<EventListener> listeners = new Vector<>();

/**
* 注册监听器
* @param eventListener
*/
public void addEventListener(EventListener eventListener) {
if (!listeners.contains(eventListener)) {
listeners.add(eventListener);
}
}

/**
* 移除监听器
* @param eventListener
*/
public void removeEventListener(EventListener eventListener) {
listeners.remove(eventListener);
}

/**
* 接收外部的事件->将事件交给事件监听者来处理
* @param event
*/
public void notifyListenerEvents(EventObject event) {
for (EventListener eventListener : listeners) {
((MyEventListener)eventListener).handleEvent(event);
}
}
}
jdk中监听器模式的实现

jdk针对监听器模式并未定义太多的实现,只是定义了一个EventListener接口和一个EventObject类,我们可以扩展EventListener接口来定义处理EventObject的方法。在EventObject中有一个属性Object:source,该属性可以在定义EventObject的时候,传入一些参数值。

public interface EventListener {

}
public class EventObject implements java.io.Serializable {

protected transient Object source;

public EventObject(Object source) {
if (source == null)
throw new IllegalArgumentException("null source");

this.source = source;
}

public Object getSource() {
return source;
}

public String toString() {
return getClass().getName() + "[source=" + source + "]";
}
}
spring中监听器模式的实现

在spring中定义了ApplicationListener接口和ApplicationEvent类,其中ApplicationListener接口实现了jdk中定义的EventListener接口,并定义了onApplicationEvent方法来处理事件,并且每个ApplicationListener只会处理特定的事件。ApplicationEvent类继承了jdk中定义的EventObject类,用以定义事件对象。

// 扩展的事件监听器接口->采用泛型
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

void onApplicationEvent(E event);
}

// 扩展的EventObject
public abstract class ApplicationEvent extends EventObject {
private static final long serialVersionUID = 7099057708183571937L;

private final long timestamp;

public ApplicationEvent(Object source) {
super(source);
this.timestamp = System.currentTimeMillis();
}

public final long getTimestamp() {
return this.timestamp;
}

}
spring中监听器模式的使用
/**
* @Author long
* @Date 2019/9/13 11:46
*/
public class App {

public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
// 注册监听器
context.addApplicationListener(new ApplicationListener<MyApplicationEvent>() {
// 接收到事件
@Override
public void onApplicationEvent(MyApplicationEvent event) {
System.out.println(event.getSource());
}
});
context.refresh();
// 发布事件
context.publishEvent(new MyApplicationEvent("study spring!"));
}
}

class MyApplicationEvent extends ApplicationEvent{
MyApplicationEvent(Object source) {
super(source);
}
}