插件机制概览
这篇文档说明 Geelato 当前插件机制的整体结构、目录约定和运行时角色划分。
本文主要基于:
geelato-pluginsplugins服务端插件开发指引.md- Runtime 中的插件装配与管理类
整体结构
当前插件机制可以分成三层:
- 插件运行时
- 插件接口契约
- 插件实现工程
对应到当前仓库,分别是:
- 运行时装配与管理:
geelato-community/geelato-web-runtime/.../plugin
- 插件接口与共享契约:
geelato-plugins/geelato-plugin-all
- 插件实现:
geelato-plugins/geelato-example-plugingeelato-plugins/geelato-logging-plugingeelato-plugins/geelato-ocr-plugin
当前运行时核心类
PluginConfiguration
运行时通过:
PluginConfiguration
创建两个关键 Bean:
SpringPluginManagerUpdateManager
其中:
SpringPluginManager- 负责插件目录扫描、插件类加载、扩展点管理
UpdateManager- 负责插件仓库更新能力
PluginConfigurationProperties
插件路径相关配置统一来自:
geelato.plugin.pluginDirectorygeelato.plugin.pluginRepository
当前默认值是:
pluginDirectory = pluginspluginRepository = plugins/repository
这两个目录在启动时会自动创建。
PluginBeanProvider
业务侧调用插件扩展时,统一通过:
PluginBeanProvider
按:
- 扩展接口类型
pluginId
获取插件实例。
PluginManagerController
当前运行时还提供了一个插件管理接口:
/api/pm/*
目前已暴露:
GET /api/pm/listGET /api/pm/switchStatusGET /api/pm/logGET /api/pm/clearLog
也就是说,当前管理端已支持:
- 查看插件列表
- 启用插件
- 禁用插件
- 查看插件日志
- 清空插件日志
当前目录约定
插件源码工程
插件源码集中在:
d:\geelato\geelato-enterprise\geelato-plugins
这里是插件开发与打包工程,不是 Runtime 直接扫描的插件目录。
它当前是一个 Maven 聚合工程,子模块包括:
geelato-plugin-allgeelato-logging-plugingeelato-example-plugingeelato-ocr-plugin
运行时插件目录
实际运行时插件目录位于:
d:\geelato\geelato-enterprise\plugins
这里当前可以看到:
- 已构建的插件包,例如
example-plugin-0.0.1-SNAPSHOT.jar - 目录型插件,例如
hello-plugin - 仓库描述文件:
plugins.jsonrepositories.json
- 插件日志目录:
plugins/logs
所以开发态和运行态是两套目录:
geelato-plugins- 负责开发、编译、打包
plugins- 负责部署、加载、日志、仓库描述
插件接口层如何设计
当前插件机制不是让主工程直接依赖某个插件实现类,而是先抽象扩展点接口。
基础扩展点接口位于:
PluginExtensionPoint
它继承:
org.pf4j.ExtensionPoint
业务插件接口再继承 PluginExtensionPoint,例如:
cn.geelato.plugin.example.Greeting
这种设计的意义是:
- 宿主工程只依赖接口
- 插件实现可独立替换
- 多个插件可以围绕同一扩展点演进
当前插件实现的典型结构
以 geelato-example-plugin 为例,当前结构包含:
- 插件主类
HelloPlugin - Spring 配置类
ExamplePluginConfiguration - 扩展实现类
HelloGreeting plugin.properties
其中:
HelloPlugin- 继承
SpringPlugin - 创建插件自己的 Spring
ApplicationContext
- 继承
HelloGreeting- 使用
@Extension标记为 PF4J 扩展实现
- 使用
ExamplePluginConfiguration- 提供插件内部自己的 Bean
所以当前插件并不是一个简单 jar,而是:
- 有独立扩展点实现
- 有独立插件上下文
- 可借助 Spring 管理内部依赖
调用模式
当前宿主工程调用插件的标准方式是:
- 注入
PluginBeanProvider - 按扩展接口和
pluginId获取插件实例 - 调用扩展方法
因此主工程与插件之间的边界是:
- 接口 + 插件 ID
而不是:
- 直接 new 某个插件类
当前实现下“加载插件”怎么理解
当前实现层面,插件加载主要依赖:
SpringPluginManager(pluginDirectory)
这表示 Runtime 会以:
geelato.plugin.pluginDirectory
指定的目录作为插件根目录。
插件需要先被打包并放入这个目录,运行时才能识别和管理。
从当前代码来看,管理端明确暴露的是:
- 启用
- 禁用
而不是完整的上传、安装、删除控制器。
因此当前“插件机制”更准确地说是:
- 具备目录扫描与运行期启停基础
- 具备仓库管理器对象
- 但安装 / 卸载 UI 与 API 仍偏基础
当前已存在的插件仓库描述
运行目录下已经存在:
plugins/repositories.jsonplugins/plugins.json
说明当前实现已经预留了:
- 文件夹仓库
- 插件发布清单
这部分会在“插件仓库配置”页展开说明。