Skip to content

Commit ca11af8

Browse files
committed
Add a set of event system with strong generality;
1 parent ac8ad15 commit ca11af8

13 files changed

+362
-0
lines changed
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package net.lamgc.utils.event;
2+
3+
import java.lang.reflect.Method;
4+
import java.lang.reflect.Modifier;
5+
import java.util.HashMap;
6+
import java.util.HashSet;
7+
import java.util.Set;
8+
9+
public class BasicEventHandlerList implements EventHandlerList {
10+
11+
private HashMap<Class<? extends EventObject>, HashSet<Method>> eventMethodMap = new HashMap<>();
12+
13+
@Override
14+
public Set<Method> getEventHandlerMethod(Class<? extends EventObject> eventObject) {
15+
return eventMethodMap.get(eventObject);
16+
}
17+
18+
@Override
19+
public void addEventHandler(Class<? extends EventHandler> eventHandler) {
20+
Method[] methods = eventHandler.getDeclaredMethods();
21+
for(Method method : methods){
22+
int modifiers = method.getModifiers();
23+
if(!Modifier.isPublic(modifiers) || Modifier.isAbstract(modifiers) || Modifier.isInterface(modifiers)){
24+
//System.out.println("方法不是公开的/抽象方法/接口方法: " + modifiers);
25+
continue;
26+
}
27+
Class<?>[] parameterTypes = method.getParameterTypes();
28+
if(parameterTypes.length != 1){
29+
//System.out.println("参数过多: " + parameterTypes.length);
30+
continue;
31+
}
32+
if(!EventObject.class.isAssignableFrom(parameterTypes[0])){
33+
//System.out.println("不是EventObject子类");
34+
continue;
35+
}
36+
addEventHandlerMethod((Class<? extends EventObject>) parameterTypes[0], method);
37+
}
38+
}
39+
40+
@Override
41+
public void addEventHandlerMethod(Class<? extends EventObject> eventObject, Method eventHandlerMethod) {
42+
if(!eventMethodMap.containsKey(eventObject)){
43+
eventMethodMap.put(eventObject, new HashSet<>());
44+
}
45+
eventMethodMap.get(eventObject).add(eventHandlerMethod);
46+
//System.out.println("已添加新的Handler方法: Class[" + eventHandlerMethod.getDeclaringClass().getSimpleName() + "] methodName[" + eventHandlerMethod.getName() + "] eventObject[" + eventObject.getSimpleName() + "]");
47+
}
48+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package net.lamgc.utils.event;
2+
3+
import java.lang.reflect.InvocationTargetException;
4+
import java.lang.reflect.Method;
5+
import java.util.Set;
6+
import java.util.concurrent.ThreadPoolExecutor;
7+
import java.util.concurrent.TimeUnit;
8+
9+
/**
10+
* 事件执行器.
11+
*/
12+
public class EventExecutor {
13+
14+
private final EventHandlerList eventHandlerList = new BasicEventHandlerList();
15+
16+
private final EventHandlerObjectMap eventHandlerObjectMap = new HashHandlerObjectMap();
17+
18+
private final ThreadPoolExecutor threadPoolExecutor;
19+
20+
/**
21+
* 构造一个EventExecutor
22+
* @param threadPoolExecutor 设置线程池, 线程池将用于执行Handler中的EventMethod.
23+
*/
24+
public EventExecutor(ThreadPoolExecutor threadPoolExecutor) {
25+
this.threadPoolExecutor = threadPoolExecutor;
26+
}
27+
28+
/**
29+
* 添加EventHandler
30+
* @param handler EventHandler对象
31+
* @throws IllegalAccessException 当EventHandler内方法不为Public时可能会抛出,
32+
* 是否抛出由{@link EventHandlerList}所使用的实现决定
33+
*/
34+
public void addHandler(EventHandler handler) throws IllegalAccessException {
35+
eventHandlerObjectMap.addHandlerObject(handler);
36+
eventHandlerList.addEventHandler(handler.getClass());
37+
}
38+
39+
/**
40+
* 投递事件.
41+
* 事件将会以方法为单位执行.
42+
* @param eventObject 带有事件参数的事件对象
43+
*/
44+
public void executor(final EventObject eventObject){
45+
Set<Method> eventHandlerMethod = eventHandlerList.getEventHandlerMethod(eventObject.getClass());
46+
if(eventHandlerMethod == null){
47+
return;
48+
}
49+
eventHandlerMethod.forEach(method -> {
50+
EventHandler handler = eventHandlerObjectMap.getHandlerObject(method.getDeclaringClass());
51+
threadPoolExecutor.execute(() -> {
52+
try {
53+
method.invoke(handler, eventObject);
54+
} catch (IllegalAccessException | InvocationTargetException e) {
55+
e.printStackTrace();
56+
}
57+
});
58+
});
59+
}
60+
61+
/**
62+
* 等待任务线程池内的任务执行完成.
63+
* @param timeout 时间
64+
* @param unit 时间单位
65+
* @throws InterruptedException 当发生死锁时抛出
66+
*/
67+
public void awaitEventExecutor(long timeout, TimeUnit unit) throws InterruptedException {
68+
threadPoolExecutor.awaitTermination(timeout, unit);
69+
}
70+
71+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package net.lamgc.utils.event;
2+
3+
/**
4+
* 用于存储事件处理方法的类所需要实现的空接口.
5+
* 标识该类存在事件处理方法.
6+
*/
7+
public interface EventHandler {
8+
9+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package net.lamgc.utils.event;
2+
3+
import java.lang.reflect.Method;
4+
import java.util.Set;
5+
6+
/**
7+
* 事件处理方法列表.
8+
* 用于根据{@link EventObject}存储事件处理方法.
9+
*/
10+
public interface EventHandlerList {
11+
12+
/**
13+
* 获取以指定EventObject为参数的Method
14+
* @param eventObject 指定的EventObject
15+
* @return 返回Method set, 如果未找到将返回空Set对象
16+
*/
17+
Set<Method> getEventHandlerMethod(Class<? extends EventObject> eventObject);
18+
19+
/**
20+
* 添加EventHandler.
21+
* EventHandler内所有形参为(EventObject)的方法收集为事件方法.
22+
* @param eventHandler EventHandler对象
23+
* @throws IllegalAccessException 当Method不为Public时抛出
24+
*/
25+
void addEventHandler(Class<? extends EventHandler> eventHandler) throws IllegalAccessException;
26+
27+
/**
28+
* 添加单个EventHandlerMethod
29+
* @param eventObject 方法所属对象
30+
* @param eventHandlerMethod 事件处理方法
31+
*/
32+
void addEventHandlerMethod(Class<? extends EventObject> eventObject, Method eventHandlerMethod);
33+
34+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package net.lamgc.utils.event;
2+
3+
/**
4+
* EventHandler对象存储Map.
5+
* 用于对EventHandler对象进行存储而无需重新实例化.
6+
*/
7+
public interface EventHandlerObjectMap {
8+
9+
/**
10+
* 添加新的EventHandler对象
11+
* @param eventHandler EventHandler对象
12+
*/
13+
void addHandlerObject(EventHandler eventHandler);
14+
15+
/**
16+
* 通过Class获取EventHandler对象
17+
* @param eventHandlerClass EventHandler的Class对象
18+
* @return 如果找到则返回EventHandler对象, 无则返回null
19+
*/
20+
EventHandler getHandlerObject(Class<?> eventHandlerClass);
21+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package net.lamgc.utils.event;
2+
3+
/**
4+
* 事件参数对象所要实现的空接口.
5+
*/
6+
public interface EventObject {
7+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package net.lamgc.utils.event;
2+
3+
import java.util.HashMap;
4+
5+
public class HashHandlerObjectMap implements EventHandlerObjectMap {
6+
7+
private final HashMap<Class<? extends EventHandler>, EventHandler> handlerMap = new HashMap<>();
8+
9+
@Override
10+
public void addHandlerObject(EventHandler eventHandler) {
11+
handlerMap.put(eventHandler.getClass(), eventHandler);
12+
}
13+
14+
@Override
15+
public EventHandler getHandlerObject(Class<?> eventHandlerClass) {
16+
return handlerMap.get(eventHandlerClass);
17+
}
18+
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package net.lamgc.utils.event;
2+
3+
import org.junit.Test;
4+
5+
import java.util.concurrent.ArrayBlockingQueue;
6+
import java.util.concurrent.ThreadPoolExecutor;
7+
import java.util.concurrent.TimeUnit;
8+
9+
public class EventExecutorTest {
10+
11+
private static void handler(SimpleEventObject event) {
12+
}
13+
14+
@Test
15+
public void executorTest() throws IllegalAccessException, InterruptedException {
16+
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
17+
1,
18+
Runtime.getRuntime().availableProcessors() / 2,
19+
30L, TimeUnit.SECONDS,
20+
new ArrayBlockingQueue<>(10)
21+
);
22+
threadPoolExecutor.setRejectedExecutionHandler((r, executor) -> {
23+
try {
24+
executor.getQueue().put(r);
25+
} catch (InterruptedException e) {
26+
throw new RuntimeException(e);
27+
}
28+
});
29+
EventExecutor executor = new EventExecutor(threadPoolExecutor);
30+
executor.addHandler(new SimpleEventHandler());
31+
executor.addHandler(new SimpleEventHandler2());
32+
executor.addHandler(new SimpleEventHandler3());
33+
executor.addHandler(new SimpleEventHandler4());
34+
executor.addHandler(new SimpleEventHandler());
35+
executor.executor(new SimpleEventObject(1, "HelloWorld"));
36+
executor.awaitEventExecutor(10L, TimeUnit.SECONDS);
37+
}
38+
39+
40+
41+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package net.lamgc.utils.event;
2+
3+
public class SimpleEventHandler implements EventHandler {
4+
5+
public void simpleEventHandler1(SimpleEventObject event){
6+
System.out.println(this.getClass().getSimpleName() + " - 1[" + event.errorCode + "] " + event.msg);
7+
}
8+
9+
public void simpleEventHandler2(SimpleEventObject event){
10+
System.out.println(this.getClass().getSimpleName() + " - 2[" + event.errorCode + "] " + event.msg);
11+
}
12+
13+
public void simpleEventHandler3(SimpleEventObject event){
14+
System.out.println(this.getClass().getSimpleName() + " - 3[" + event.errorCode + "] " + event.msg);
15+
}
16+
17+
public void simpleEventHandler4(SimpleEventObject event){
18+
System.out.println(this.getClass().getSimpleName() + " - 4[" + event.errorCode + "] " + event.msg);
19+
}
20+
21+
public void simpleEventHandler5(SimpleEventObject event){
22+
System.out.println(this.getClass().getSimpleName() + " - 5[" + event.errorCode + "] " + event.msg);
23+
}
24+
25+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package net.lamgc.utils.event;
2+
3+
public class SimpleEventHandler2 implements EventHandler {
4+
5+
public void simpleEventHandler1(SimpleEventObject event){
6+
System.out.println(this.getClass().getSimpleName() + " - 1[" + event.errorCode + "] " + event.msg);
7+
}
8+
9+
public void simpleEventHandler2(SimpleEventObject event){
10+
System.out.println(this.getClass().getSimpleName() + " - 2[" + event.errorCode + "] " + event.msg);
11+
}
12+
13+
public void simpleEventHandler3(SimpleEventObject event){
14+
System.out.println(this.getClass().getSimpleName() + " - 3[" + event.errorCode + "] " + event.msg);
15+
}
16+
17+
public void simpleEventHandler4(SimpleEventObject event){
18+
System.out.println(this.getClass().getSimpleName() + " - 4[" + event.errorCode + "] " + event.msg);
19+
}
20+
21+
public void simpleEventHandler5(SimpleEventObject event){
22+
System.out.println(this.getClass().getSimpleName() + " - 5[" + event.errorCode + "] " + event.msg);
23+
}
24+
25+
}

0 commit comments

Comments
 (0)