# damibus
**Repository Path**: noear/damibus
## Basic Information
- **Project Name**: damibus
- **Description**: DamiBus,专为本地(单体)多模块之间交互解耦而设计(尤其是未知模块、隔离模块)。也是 DDD 开发的良配。瞬发 5000万/秒
- **Primary Language**: Java
- **License**: Apache-2.0
- **Default Branch**: main
- **Homepage**: https://solon.noear.org/article/damibus
- **GVP Project**: No
## Statistics
- **Stars**: 221
- **Forks**: 47
- **Created**: 2023-09-08
- **Last Updated**: 2025-09-28
## Categories & Tags
**Categories**: utils
**Tags**: ddd, EventBus, rpc
## README
DamiBus
本地(单体)多模块过程调用框架(主打解耦)
https://solon.noear.org/article/damibus
DamiBus,专为本地(单体)多模块之间交互解耦而设计(尤其是未知模块、隔离模块、领域模块)。也是 DDD 开发的良配。
### 特点
结合总线与响应的概念,可作事件分发,可作接口调用,可作响应式流生成,等等。
* 支持事务传导(同步分发、异常透传)
* 支持拦截器(方便跟踪)
* 支持监听者排序
* 支持附件传递(多监听时,可相互合作)
* 支持泛型
* 支持回调和响应式流
* 支持最高 5000万/秒 的转发能力(测试机器:2020 macbook pro x86)
* 支持 Bus 和 Lpc 两种体验风格
### 与常见的 EventBus、ApiBean 的区别
| | DamiBus | EventBus | ApiBean |
|-------|---------|----------|----------|
| 广播模式 | 有 | 有 | 无 |
| 请求与响应模式 | 有 | 无 | 有 |
| 响应式流模式 | 有 | 无 | 有 |
| | | | |
| 耦合 | 弱- | 弱+ | 强++ |
### 依赖配置
```xml
org.noear
dami2
2.0.0
```
如果涉及类加载器隔离:请在主程序标为编译,在其它模块标为可选。
### 简单示例
#### demo11_send
```java
public class Deom11 {
static String topic = "demo.hello";
public static void main(String[] args) {
//监听事件
Dami.bus().listen(topic, event -> {
System.err.println(event.getPayload()); //可以有多个订阅
});
//发送事件
Dami.bus().send(topic, "{name:'noear',say:'hello'}");
}
}
```
#### demo12_call
```java
public class Demo12 {
static String topic = "demo.hello";
public static void main(String[] args) throws Exception {
//监听调用事件
Dami.bus().listen(topic, (event, data, sink) -> {
System.err.println(data);
sink.complete("hi!");
});
//发送调用事件
String rst1 = Dami.bus().call(topic, "world").get();
//发送事件(调用) //支持应急处理(当没有订阅时启用)
//String rst1 = Dami.bus().call(topic, "world", r -> r.complete("def")).get();
System.out.println(rst1);
}
}
```
### demo13_stream
```java
public class DemoApp {
static String topic = "demo.hello";
public static void main(String[] args) {
//监听流事件
Dami.bus().listen(topic, (event, att, data, sink) -> {
System.err.println(data);
sink.onNext("hi");
sink.onComplete();
});
//发送流事件
Flux.from(Dami.bus().stream(topic, "hello")).doOnNext(item -> {
System.err.println(item);
}).subscribe();
}
}
```
#### demo31_lpc
使用 ioc 适配版本更简便,详情:[dami2-solon-plugin](dami2-solon-plugin)、[dami2-springboot-starter](dami2-springboot-starter)
```java
//服务消费者接口
public interface UserService {
Long getUserId(String name);
}
//通过约定保持与 UserService 相同的接口定义(或者实现 UserService 接口,但会带来依赖关系)
public class UserServiceImpl { // implements UserService
public Long getUserId(String name) {
return Long.valueOf(name.hashCode());
}
}
public class Demo31 {
public static void main(String[] args) {
//注册服务提供者
UserServiceImpl userServiceImpl = new UserServiceImpl();
Dami.lpc().registerProvider(topicMapping, userServiceImpl);
//创建服务消费者(接口代理)
UserService userService = Dami.lpc().createConsumer(topicMapping, UserService.class);
//发送测试
Long userId = userService.getUserId("dami");
System.err.println("收到:响应:userId:" + userId);
//注销服务提供者
Dami.lpc().unregisterProvider(topicMapping, userServiceImpl);
}
}
```
### 定制能力(详见事件路由器:[Router.md](Router.md))
```java
public class Demo15_path {
public void main(){
//切换为 path 模式匹配路由器(支持 * 和 ** 占位符;支持 / 或 . 做为间隔)
DamiConfig.configure(new PathTopicEventRouter());
//拦截
Dami.bus().listen("demo/a/*", (event) -> {
System.err.println(event.getPayload());
});
//发送事件
Dami.bus().send("demo/a/1", "world1");
Dami.bus().send("demo/a/2", "world2");
}
}
```
```java
public class Demo15_tag {
public void main(){
//切换为 tag 模式匹配路由器(":"前为主题,后按 "," 号分割作为tag)
DamiConfig.configure(new TagTopicEventRouter());
//拦截
Dami.bus().listen("demo.a:id", (event) -> {
System.err.println(event.getPayload());
});
//发送事件
Dami.bus().send("demo.a:id", "world1");
Dami.bus().send("demo.a:id,name", "world2");
}
}
```
### 可无依赖接口实现
详情:[dami2-solon-plugin](dami2-solon-plugin)、[dami2-springboot-starter](dami2-springboot-starter)
```java
@DamiTopic("event.user")
public interface EventUserService {
User getUser(long userId); //方法的主题 = topicMapping + "." + method.getName() //方法不能重名
}
//通过约定保持与 EventUserService 相同的接口定义(或者实现 EventUserService 接口,这个会带来依赖关系)
@DamiTopic("event.user")
public class EventUserServiceListener { // implements EventUserService // 它相当于是个实现类
public User getUser(long userId) {
return new User(userId);
}
}
@SolonTest
public class Demo81 {
@Inject
EventUserService eventUserService;
@Test
public void main(){
User user = eventUserService.getUser(99);
assert user.getUserId() == 99;
}
}
```