Skip to content

关于扩展点SPI方案的重构 #1092

Closed
@yanrongzhen

Description

@yanrongzhen

需求建议

重构扩展点(SPI)功能

现有的扩展点的注册和使用都是通过ServiceLoader实现.
(cn.hippo4j.common.spi.DynamicThreadPoolServiceLoader)

有什么问题:

  1. 每次使用前都要去关注是否注册到了register map中.
  2. 由于一个扩展点接口可能拥有多个实现, 需要写很多冗余的代码去触发和判断List当中是否有满足条件的结果.

怎么解决:

注册的问题 - 结合spring

在Spring启动时, 扫描容器中所有被打上@Realization(表示扩展点的实现类) 注解的 Bean, 并注册到ExtensionRegistry当中, 是一个 Map<Class<?>, List> extensionMap (扩展点接口类 <-> 扩展点实现list) 的注册表.
使用时, 通过调用的扩展点接口类, 在注册表当中找到对应的实现类对象List.

结果处理的问题 - 引入结果规约处理器Reducer

Reducer本质上是一个DataCollector, 通过统一的ExtensionInvoker触发器, 传入扩展点接口class, callback行为, 和一个Reducer.

触发代码可能如下: (比如场景是想找到第一个结果为非空的MyObject对象)

MyObject result = ExtensionInvoker.reduceExecute
                (ITestExtension.class, ITestExtension::foo, request, Reducers.firstOf(Objects::nonNull));

函数原型:

public static <T extends IExtension, E, R> R reduceExecute(Class<T> targetClz, ExtensionCallback<T, E> callback,
                                                               Reducer<T, E, R> reducer);

这样我们就可以通过一行代码干净的解决扩展注册/寻找和结果处理的问题

规约函数, 可能出现如下几种类型:

  1. ResultObj FirstOf(Predicate p) -- 第一个遇到结果满足p的, 直接返回
  2. Boolean AllMatch(Predicate p) -- 判断执行结果是否都满足p
  3. Boolean AnyMatch(Predicate p) -- 判断任一执行结果是否满足p
  4. .... 可以继续扩展规约函数 (FlatMap, FlatList 等等)

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions