扩展机制
ApiGo 在三个层面提供扩展能力:数据源驱动(接入新的数据库/存储)、结果处理插件(加工返回数据)、运行配置钩子(不改代码调整行为)。本文从代码结构角度说明扩展点如 何加载、如何执行,使用说明见 数据插件 与 数据源管理。
数据源驱动 SPI
加载方式
数据源驱动基于 Java ServiceLoader 发现,无需修改核心代码:
新增驱动需要三步:
- 实现
DataSourceDriver接口(或继承DefaultDataSourceDriver)。 - 在模块的
META-INF/services/cn.apigo.core.spi.datasource.DataSourceDriver中写入实现类全名。 - 将模块加入
apigo-api与apigo-admin的依赖,使两端的ServiceLoader都能发现。
驱动名称必须唯一
DataSourceManager 初始化时按 getName() 注册;名称重复或为空会直接抛出 51003/51004 异常,阻止服务启动。类型匹配时统一转小写。
接口职责
| 方法 | 作用 |
|---|---|
getName() | 驱动类型标识,与数据源配置的 datasourceType 对应 |
isRelational() | 是否关系型;决定是否走事务与 JDBC 连接池 |
supportsTransaction() / supportsStatement() / supportsMetaData() | 能力声明,执行引擎据此选择执行路径 |
test() | 数据源连通性测试 |
init() / destroy() | 连接池或客户端生命周期 |
getMetaData() | 库表结构浏览(表、字段、索引) |
getStatement() | SQL/查询语句执行 |
两类驱动
- JDBC 驱动:
JdbcDataSourceDriver继承DefaultDataSourceDriver,统一处理连接池、事务、元数据与StatementMapper。MySQL、Oracle、PostgreSQL 等关系型数据库共用这一实现,差异由 JDBC URL 与驱动包决定。 - 原生驱动:MongoDB、Elasticsearch 直接实现
DataSourceDriver,声明isRelational=false,自行管理客户端与查询语句。这类数据源不参与 SQL 事务,元数据能力也按驱动实现。
连接池隔离
DataSourceManager 在进程内维护三类映射:
| 映射 | 内容 |
|---|---|
pluginType | 驱动类型 → 驱动实例 |
pluginDataSourcePool | 数据源 ID → 原生驱动实例 |
DATA_SOURCE_POOL_JDBC | 数据源 ID → JDBC DataSource |
同一数据源切换驱动类型时,会释放旧类型的资源,避免连接池泄漏。管理端多实例各自维护本地连接池,共享的只是 Redis 中的配置快照。
结果处理插件
执行链
插件在接口执行完成、响应写出之前运行,输入是结果数据,输出是加工后的数据。执行器 PluginExecutor 的工作方式:
- 解析接口上的
pluginConfigJSON。结构为{ "<pluginType>": { "enabled": true, ... } }。 - 按
getType()从 Spring 容器注册的PluginHandler中匹配处理器。 - 只保留
enabled=true的插件,按getOrder()升序执行。 - 每个处理器的输出作为下一个处理器的输入。
内置处理器
| 类型 | 顺序 |
|---|