DamiBus，专为本地（单体）多模块之间交互解耦而设计（尤其是未知模块、隔离模块、领域模块）。也是 DDD 开发的良配。

---


v2.x 相对于 v1.x 做了三个重要的改变（没法向下兼容）：

* 做了简化，只有一个 `send` 发送接口。化繁为简
  * （原来还有 `sendAndRequest`、`sendAndSubscribe`，且有专门的处理）。
* 重新设计了 `payload` 概念和 `result` 机制，给了它自由定制（或配置）的空间
  * （原来只把它想象为数据）。现在可以是数据，可以是行为，也可以是混合
* 重新设计了泛型（用来指定 `payload` 类型）
  * （原来用它指定输入输出数据）。缺少自由




### 1、新的依赖包（使用 dami2）

新的包名改成了 `dami2`。因为没法兼容 v1.x，所以采用与 v1.x “共存”的策略（方便升级过度）。

```xml
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>dami2</artifactId>
    <version>2.0.4</version>
</dependency>
```

或者 IOC 框架集成包： 

```xml
<dependency>
    <groupId>org.noear</groupId>
    <artifactId>dami2-solon-plugin</artifactId> <!-- 或  springboot-solon-plugin -->
    <version>2.0.4</version>
</dependency>
```


###  2、Bus 接口变化说明

方法名变化：

| 旧接口（v1.x）                              | 新接口（v2.x）           | （按新版意图）备注 |
| --------------------------- | ----------------- | -------- |
| `Dami.bus().send()`                        | `Dami.bus().send()`     | 发送事件     |
| `Dami.bus().sendAndRequest()`       | `Dami.bus().call()`        | 发送调用事件     |
| `Dami.bus().sendAndSubscribe()`     | `Dami.bus().stream()`   | 发送流事件     |

泛型使用变化（没法向下兼容）：

| 旧接口（v1.x）                              | 新接口（v2.x） | （按新版意图）备注 |
| --------------------------- | ----------------- | -------- |
| `Dami.<String,String>bus().send()` <br/>//在前声明（固定2个） | `Dami.bus().<String>send()`   <br/>//在后声明（个数由场景定）       | 泛型 |

关于 `call` 和 `stream` 的说明：

* 是在体验层定制（或配置）出来的。（旧的 sendAndRequest 和 sendAndSubscribe 是内部实现）
* 在异步用况下，可以传导异常。（旧的 sendAndRequest 和 sendAndSubscribe 不行）

### 3、Bus 概念变化说明（没法向下兼容）


| 旧概念（v1.x）                              | 新概念（v2.x）           | （按新版意图）备注 |
| --------------------------- | ----------------- | -------- |
| `Payload`                                     | `Event`                      | 事件     |
| `Content`                                     | `Payload`                   | 荷载（强调自由定制）     |

新的事件（event）由主题（topic）、荷载（payload）、附件（attach）三者，以及是否已处理标识组成。

### 4、Api 接口变化说明（新的叫：Lpc）

lpc 是相对于 rpc 的概念：本地（单体）过程（无耦合）调用。内部是基于 `Dami.bus().call()`（即调用事件） 的包装

| 旧接口（v1.x）                                     | 新接口（v2.x）                          |  （按新版意图）备注             |
| ------------------------------- | ------------------------- | ----------------------- |
| `Dami.api().registerListener()`                 | `Dami.lpc().registerProvider()`    | 注册服务提供者（监听事件）     |
| `Dami.api().createSender()`                    | `Dami.lpc().createConsumer()`    | 创建服务消费者（发送事件）     |

新的概念参照了 rpc 风格：服务提供者，服务消费者。


### 5、新版示例（老用户一看，就有数了）

* bus send

```java
public void case_send() {
    //监听事件
    Dami.bus().listen(topic, event -> {
        System.err.println(event.getPayload()); 
    });

    //发送事件
    Dami.bus().send(topic, "hello");
}
```



* bus call

```java
public void case_call() throws Exception {
    //监听调用事件
    Dami.bus().listen(topic, (event, data, sink) -> {
        System.err.println(data);
        sink.complete("hi!"); 
    });

    //发送调用事件 - 等待风格
    String rst = Dami.bus().<String, String>call(topic, "hello").get();
    
    //发送调用事件 - 回调风格
    bus.<String, String>call(topic, "world").whenComplete((rst, err) -> {
        System.out.println(rst);
    });
}
```


* bus stream

```java
public void case_stream() {
    //监听流事件
    Dami.bus().<String, String>listen(topic, (event, att, data, sink) -> {
        System.err.println(data);
        sink.onNext("hi");
        sink.onComplete();
    });

    //发送流事件（可以对接不同的响应式框架）
    Flux.from(Dami.bus().<String, String>stream(topic, "hello")).doOnNext(item -> {
        System.err.println(item);
    });
}
```

* lpc (like rpc)

```java
//服务消费者（发送事件）
public interface UserService {
    Long getUserId(String name);
}

//服务提供者（监听事件）
public class UserServiceImpl { //这里不用实现接口（参数名对上就好）。从而实现解耦
    public Long getUserId(String name) {
        return 99L;
    }
}

public void case_lpc() {
    //注册服务提供者（监听事件）
    Dami.lpc().registerProvider("demo", new  UserServiceImpl());

    //生成服务消费者（发送事件）
    UserService userService = Dami.lpc().createConsumer("demo", UserService.class);
    
    //测试
    userService.getUserId("noear");
}
```

