# enet
**Repository Path**: xnat/enet
## Basic Information
- **Project Name**: enet
- **Description**: 小清新响应式事件驱动工具
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 30
- **Forks**: 7
- **Created**: 2019-01-14
- **Last Updated**: 2024-12-19
## Categories & Tags
**Categories**: utils
**Tags**: 事件驱动, 事件, 异步事件, 事件总线
## README
# 介绍
响应式事件驱动工具
ep.fire("event1", "参数1", "参数2")
工具包含三个组件: EL(事件监听), EP(事件中心), EC(事件执行上下文)
# 安装教程
```xml
cn.xnatural
enet
1.1.2
```
# 事件驱动库原理

1. 事件监听器
```java
// 定义监听
public class TestEP {
// 用@EL注解标记一个方法为事件监听
@EL(name = "hello")
void hello() {
System.out.println("hello world");
}
}
```
2. 事件中心
```java
// 方法1: 创建一个事件中心
final EP ep = new EP();
```
```java
// 方法2: 创建一个事件中心
final EP ep = new EP(Executors.newFixedThreadPool(2, new ThreadFactory() {
final AtomicInteger i = new AtomicInteger();
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "ep-" + i.incrementAndGet());
}
}));
```
3. 注册事件
```java
// 会解析对象中所有包含@EL方法
ep.addListenerSource(new TestEP());
```
4. 触发事件
```java
ep.fire("hello"); // 打印: hello world
```
# 其他用法
## 带参数事件
```java
@EL(name = "event1")
void hello(String p1, Integer p2) {
System.out.println("p1: " + p1 + ", p2");
}
// 传参
ep.fire("event1", "参数1", 2);
// 默认填充参数为null
ep.fire("event1");
```
## 有返回的事件
```java
@EL(name = "event1")
String event1(String p1) { return p1;}
// 触发
Object value = ep.fire("event1", "xxx");
```
## 多返回值
```java
new EP().addListenerSource(new Object() {
@EL(name = "e1")
String m1() { return "p1"; }
}).addListenerSource(new Object() {
@EL(name = "e1")
String m11() { return "p11"; }
}).fire("e1", ec -> {
Assertions.assertTrue(ec.results().stream().map(o -> (String) o).collect(Collectors.joining("")).equals("p1p11"));
});
```
## 事件执行完回调
```java
ep.fire("hello", (ec) -> {
// 事件结束执行
}, "参数1");
ep.fire("hello", (ec) -> {
if (ec.isSuccess()) {
// 事件成功结束后执行
}
}, "参数1");
```
## 动态监听器
```java
//1. 添加监听
ep.listen("dynEvent1", () -> {
System.out.println("执行动态事件: 无参");
});
//2. 添加带参数的监听
ep.listen("dynEvent2", (p) -> {
System.out.println("执行动态事件: 入参: " + p);
return p;
});
ep.fire("dynEvent1");
System.out.println(ep.fire("dynEvent2", "3333"));
```
## 动态事件名
```java
@EL(name = "{xx}.hello")
void xxhello() {
System.out.println("xx hello");
}
String getXx() { return "aa"; }
// ep.fire("aa.hello")
```
## 删除事件监听
```java
// 删除某个事件的监听
ep.removeEvent("dynEvent1");
```
```java
// 移除对象源的所有监听器
ep.removeSourceAllEvent(source);
```
## 同步异步
### 同步执行(默认)
```java
// 1. 监听器设置同步(默认就是同步)
@EL(name = "sync", async = false)
String syncListener(){ return "xxx";}
```
```java
// 2. 强制同步执行
Object result = ep.fireSync("sync");
```
### 异步执行
```java
// 1. 监听器设置异步
@EL(name = "async", async = true)
String asyncListener(){ return "oo"; }
```
```
// 2. 强制异步执行
ep.fireAsync("async");
```
```java
// 3. 接收异步结果
ep.fireAsync("async", ec -> {
// 异步结果: ec.result
});
```
## 执行顺序
> 同相事件名的多个监听器的执行顺序: 由@EL order 指定(默认: 0)
>> 从小到大执行, 越小越先执行
> + 先按优先级顺序执行所有同步监听器
> + 再按优先级分组执行所有异步监听器
```java
@EL(name = "order")
void order1() {log.info("同步 order1");}
@EL(name = "order", async = true)
void order2() {log.info("异步 order2");}
@EL(name = "order", async = true)
void order22() {log.info("异步 order22");}
@EL(name = "order", async = true)
void order222() {log.info("异步 order222");}
@EL(name = "order", async = true, order = 1f)
void order3() {log.info("异步 order3");}
```
> 所以会先执行 order1, 结束后再并发执行(order2,order22,order22), 结束后再执行 order3
## 执行次数限制
```java
@EL(name = "once", limit = 1, async = true)
void once() { log.info("只执行一次"); }
```
```java
ep.fire("once", ec -> {
log.info("once: success: " + ec.isSuccess() + ", isNoListener: " + ec.isNoListener());
});
ep.fire("once", ec -> {
log.info("once: success: " + ec.isSuccess() + ", isNoListener: " + ec.isNoListener());
});
```
## debug模式
日志打印事件执行前后详情
```java
// 方法1
ep.fireDebug("hello", "参数1");
```
```java
// 方法2
ep.addTrackEvent("hello");
```
## 事件执行上下文
```java
@EL(name = "ec")
String ec(EC ec, String p1) {
return p1 + ec.getAttr("key1");
}
// 每次触发一个事件 都会有一个 EC 对象(事件执行上下文)
ep.fire("ec"); // 自动创建EC对象
ep.fire(new EC("ec").args("xx").attr("key1", "oo")); // 手动创建EC对象,并设置属性. 返回: xxoo
```
## 自定临时义监听器
```java
new EP().fire(new EC("xxx"), new Listener.RunnableListener(() -> {
log.info("========RunnableListener");
}) {
@Override
protected void doInvoke(EC ec, BiConsumer