此内容，v2.9.3 后支持

### 1、构建注解的类型扩展（`@CloudEvent` 为例）

* 旧的方式。只有唯一的能力注册

```java
context.beanBuilderAdd(CloudEvent.class, (.)->{...}); //唯一的
```

```java
//体验效果（只能让 @CloudEvent 注解加在 CloudEventHandler 接口的实现类上）
@CloudEvent("demo.event2")
public class Event2 implements CloudEventHandler {
    @Override
    public boolean handle(Event event) throws Throwable {
        return true;
    }
}
```


* 新的特性。可以按类型注册扩充能力

如果想在 `@CloudEvent` 原来的能力不破坏的基础上，增加一个新的扩展接口（支持泛型接收事件的）。可以增加一个类型的能力注册。比如添加新接口 CloudEventHandlerPlus 的处理。

```java
context.beanBuilderAdd(CloudEvent.class, CloudEventHandlerPlus.class, (.)->{
    //...将 CloudEventHandler 接收的 event 数据转为目标泛型数据
});  
```

```java
//体验效果（可以加在 CloudEventHandlerPlus 接口上了，并且能自动将 Event 的数据，转为 UserEvent）
@CloudEvent("demo.event2")
public class Event2 implements CloudEventHandlerPlus<UserEvent> {
    @Override
    public boolean handle(UserEvent event) throws Throwable {
        return true;
    }
}
```


### 2、注解注解的类型扩展（`@Ds` 为例）

* 旧的方式。只能有唯一的能力注册

```java
context.beanInjectorAdd(Ds.class, (.)->{...}); //唯一的
```

如果在 wood-solon-plugin 用了这个注册。则 mybatis-solon-plugin 就不能注册。之前，每个插件者有自己的 `@Db` 注解（就是为了避免多 orm 时，产生冲突）。

* 新的特性。可以按类型注册能力

```java
//根据场景，我们不使用默认的注册
//context.beanInjectorAdd(Ds.class, (.)->{...}); //默认的


//:: wood-solon-plugin 的注册
//体验：@Ds DbContext db;
context.beanInjectorAdd(Ds.class, DbContext.class, (.)->{...});  //按类型扩展能力
//体验：@Ds UserMapper userMapper;（UserMapper extends wood:Mappable）
context.beanInjectorAdd(Ds.class, Mappable.class, (.)->{...});  //按类型扩展能力


//:: mybatis-solon-plugin 的注册
//体验：@Ds SqlSessionFactory factory;
context.beanInjectorAdd(Ds.class, SqlSessionFactory.class, (.)->{...});  //按类型扩展能力
//体验：@Ds Configuration config;
context.beanInjectorAdd(Ds.class, Configuration.class, (.)->{...});  //按类型扩展能力
//体验：@Ds UserMapper userMapper;（UserMapper extends mybatis:Mappable）
context.beanInjectorAdd(Ds.class, Mappable.class, (.)->{...});  //按类型扩展能力
```

新的方式，可支持所有的 orm 适配使用统一的注入注解（且混用时，不冲突）。在业务中，也可以发散思维：

```java
context.beanInjectorAdd(Ds.class, UserService.class, (vh, anno)->{
    //获取数据源
    DsUtils.observeDs(vh.context(), anno.value(), (dsWrap) -> {
        //比如 UserServiceImpl 需要指定一个数据源
        UserService tmp = new UserServiceImpl(dsWrap.get());
        vh.setValue(tmp);
    });
}); 
```

