一、框架实现篇?
关键角色:
- 事件源(XXXEvent):能够接收外部事件的源体,内部包含事件的类型。
- 事件监听器(XXXEventListener):能够接收事件源通知的对象。
- 事件分发器(EventDispatcher):维护事件类型与事件监听器列表的映射关系,接收事件并进行事件的派发。
- 事件监听器管理类(EventListenerManager):声明一系列的事件监听器,通过@EventAnnotation定义该事件监听器感兴趣的事件类型,最后通过反射的方式实现事件监听器自动注册到EventDispatcher。
------------------------------------------------------------------------------------------------------------
话不多说,直接上代码
-------------------------------------------------------------------------------------------------------------
(1)定义事件类型EventType
package com.example.demo.eventdriven;
/**
*
* @ClassName: EventType
* @Description: 事件类型
* @Author: liulianglin
* @DateTime 2022年4月21日 下午3:35:56
*/
public enum EventType {
LOGIN,//登陆事件
EXIT,//退出事件
;
}
(2)定义事件基类BaseEvent
package com.example.demo.eventdriven;
/**
*
* @ClassName: BaseEvent
* @Description: 基础事件类
* @Author: liulianglin
* @DateTime 2022年4月21日 下午3:34:19
*/
public class BaseEvent {
//是否在消息主线程同步执行
private boolean sync = true;
//事件类型
private final EventType evtType;
public BaseEvent (EventType evtType) {
this.evtType = evtType;
}
public BaseEvent (EventType evtType,boolean sync) {
this.evtType = evtType;
this.sync = sync;
}
public EventType getEvtType() {
return evtType;
}
/**
* 是否在消息主线程同步执行
* @return
*/
public boolean isSync() {
return sync;
}
public void setSync (boolean sync) {
this.sync = sync;
}
}
(3)定义事件监听器接口EventListener
package com.example.demo.eventdriven;
/**
*
* @ClassName: EventListener
* @Description: 事件监听接口
* @Author: liulianglin
* @DateTime 2022年4月21日 下午3:35:21
*/
public interface EventListener<E> {
/**
* 事件触发后,处理具体逻辑
* @param event
*/
public void handleEvent(E event);
}
(4)定义事件监听器管理器抽象类AbstractEventListenerManager
package com.example.demo.eventdriven;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
/**
*
* @ClassName: AbstractEventListenerManager
* @Description: 事件监听器管理者基类,通过注解实现事件监听器的自动注册
* @Author: liulianglin
* @DateTime 2022年4月21日 下午3:05:43
*
* 将要注册事件的监听器,在 AbstractEventListenerManager 子类属性中,通过注解 @EventAnnotation标记监听器所感兴趣的事件。
* 详细参见EventListenerManager类
*/
public abstract class AbstractEventListenerManager {
/**
* 初始化 注册监听器(启动程序时调用)
*/
@SuppressWarnings({ "unchecked" })
public void initEventListener () {
Field[] fields = getClass().getDeclaredFields();
for (Field f:fields) {
EventAnnotation evt = f.getAnnotation(EventAnnotation.class);
if (evt != null) {
EventType eventType = evt.eventType();
Class<?> listenClass = f.getType();
EventListener<? extends BaseEvent> newInstance;
try {
newInstance = (EventListener<? extends BaseEvent>)listenClass.getDeclaredConstructor().newInstance();
//注册事件
EventDispatcher.INSTANCE.registerEvent(eventType, newInstance);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
}
}
}
(5)定义一个事件监听器管理器实现EventListenerManager
package com.example.demo.eventdriven;
import org.springframework.stereotype.Component;
/**
*
* @ClassName: EventListenerManager
* @Description: 事件监听器管理类
* @Author: liulianglin
* @DateTime 2022年4月21日 下午3:08:38
*
* 不同的业务模块可以创建属于自己的EventListenerManager
*/
@Component
public class EventListenerManager extends AbstractEventListenerManager {
/**
* 在构造器中调用父类的initEventListener,完成下方被注解修饰的所有事件监听器自动注册到EventDispatcher
*/
public EventListenerManager() {
super.initEventListener();
}
/**
* 通过@EventAnnotation定义该事件监听器感兴趣的事件类型
*/
@EventAnnotation(eventType=EventType.LOGIN)
public ExampleEventListener exampleEvent;
//这里继续添加其他事件监听器
//@Evt(eventType=EventType.EXIT)
//public ExampleEventListener exampleEvent2;
}
这里注意:这里边的ExampleEventListener暂时还没定义,下面使用环节会定义这个类?
(6)定义一个注解EventAnnotation,用于配合AbstractEventListenerManager实现事件监听器的自动注册
package com.example.demo.eventdriven;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
*
* @ClassName: EventAnnotation
* @Description: 事件注解:指定感兴趣的事件类型
* @Author: liulianglin
* @DateTime 2022年4月21日 下午3:32:28
*/
@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface EventAnnotation {
/**事件类型*/
public EventType eventType();
}
(7)再定义一个内部异常类(非必须品)EventDrivenException,用于定义处理内部出现的异常
package com.example.demo.eventdriven;
/**
*
* @ClassName: EventDrivenException
* @Description: 事件驱动内部处理异常
* @Author: liulianglin
* @DateTime 2022年4月21日 下午3:39:16
*/
public class EventDrivenException extends RuntimeException{
public EventDrivenException(String message) {
super(message);
}
}
======================= 至此框架全部代码完毕 =============
二、框架使用篇
(1)声明一个业务事件
package com.example.demo.eventdriven;
/**
*
* @ClassName: ExampleEvent
* @Description: 示例事件(用于演示如何使用该事件驱动框架)
* @Author: liulianglin
* @DateTime 2022年4月21日 下午2:50:54
*/
public class ExampleEvent extends BaseEvent {
private String userName;
public ExampleEvent(EventType evtType, String userName) {
super(evtType);
this.userName = userName;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
}
(2)声明一个业务事件监听器
package com.example.demo.eventdriven;
/**
*
* @ClassName: ExampleEventListener
* @Description: 样例事件监听器(用于演示使用)
* @Author: liulianglin
* @DateTime 2022年4月21日 下午3:36:17
*/
public class ExampleEventListener implements EventListener<ExampleEvent> {
@Override
public void handleEvent(ExampleEvent event) {
System.out.println("开始处理"+event.getEvtType()+"事件, 当前登陆用户名称="+event.getUserName());
}
}
这里注意,自定义的事件监听器需要声明到上面的EventListenerManager内部,如下图所示?:
(3)编写测试类(基于Spring Boot环境)
package com.example.demo.eventdriven;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class EventDrivenTest {
@Test
void test() {
BaseEvent event = new ExampleEvent(EventType.LOGIN, "超级管理员");
event.setSync(false);
EventDispatcher.INSTANCE.dispatchEvent(event);
try {
System.out.println("模拟业务处理1秒钟....");
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("处理完毕,关闭");
//EventDispatcher.INSTANCE.shutdown();
}
}
测试结果:
完活儿。。。。?
|