张帆
张帆
Published on 2026-11-02 / 0 Visits
0
0

aimom 插件开发文档-JAVA版

# aimom-extends-plugins

aimom **外部扩展插件仓库**:一个仓库承载多个 aimom Java 插件。

工作方式:插件是**普通 Maven jar**(不是 Spring Bean、不是 OSGi)。应用启动时扫描 classpath 上所有 `plugin.json`(`name` 以 `@aimom` 开头的才会被发现),按 `basePackageDir` 反射实例化入口类;"打进 classpath ≠ 启用",启用状态存数据库 `applicationPlugins` 表。

## 仓库结构

aimom-extends-plugins/
├── pom.xml # 聚合 pom,继承 com.sie.aimom:aimom:1.0.0-SNAPSHOT(统一版本管理)
│ # 并为所有插件模块注入 aimom-core + lombok(provided)
└── plugin-hello-world/ # 全栈示例插件:collection + REST action + ACL + migration + i18n
└── src/main/
├── java/com/sie/aimom/plugins/helloworld/
│ ├── PluginHelloWorld.java # 插件入口(唯一 Plugin 子类,构造器 (Application, PluginOptions))
│ ├── actions/ # (可选)自定义 REST action(静态 Handler + 单例,入口类统一注册)
│ ├── collections/ # (可选)CollectionDefine 子类(框架按 basePackageDir 自动扫描)
│ ├── migrations/ # (可选)Migration 子类(类名 = migrations 表幂等键,自动扫描执行)
│ ├── constants/ # 常量类 + 字典枚举
│ ├── api/ # 对外 REST 的请求/响应 DTO
│ ├── type/ # 插件内部使用结构 bean
│ └── ai/ # (可选)AI 实现类:tools/** 工具、mcp/** MCP、aiemployees/** AI 员工
└── resources/
├── plugin.json # name=@aimom/plugin-xxx + basePackageDir
├── collections/*.json # 表结构定义(建表走 db.sync,无需手写 DDL)
├── locale/{en-US,zh-CN}.json
└── ai/ # (可选)AI 定义资源,按目录约定自动扫描,无需注册代码
├── tools//description.md # 工具描述(实现类在 java 侧 ai//tools/**)
├── skills//SKILLS.md # 技能
└── aiemployees//skills//SKILLS.md # AI 员工及其技能


## 命名契约

命名契约(`plugin.json` name ↔ Maven artifactId ↔ basePackageDir ↔ 外置 jar 文件名,任一处错位插件即"不可见")以 `.harness/rules/plugin-rule.md` 为准。

## 构建

前置:Maven 能解析平台工件——父 pom `com.sie.aimom:aimom` 与框架 jar `com.sie.aimom:aimom-core`(来自内部 Nexus,或平台方/联调环境装入本地 `~/.m2` 的快照)。本仓库不需要平台源码。

```bash
mvn clean install            # 全量构建(jar 装入 ~/.m2,供 aimom-starter 引用)
mvn clean deploy             # 发布到 Nexus(deploy 目标继承自父 pom,Nexus 凭证配在 Maven settings.xml)
mvn test -pl plugin-hello-world     # 只跑测试

规则自检:python3 .harness/scripts/check-rules.py——对命名契约、i18n、日志/异常、pom 约定等做静态校验,覆盖范围见脚本头部说明。

新增一个插件

python3 .harness/scripts/new-plugin.py qms-spc             # 生成 plugin-qms-spc
python3 .harness/scripts/new-plugin.py qms-spc --dry-run   # 只看计划不落盘

脚本内嵌模板自生成最小骨架(与范例模块解耦,不复制现有代码):模块目录 + pom(artifactId)+ plugin.json(name/basePackageDir)+ 唯一入口类(Plugin<驼峰>,仅必需构造器),并登记根 pom <modules>;不生成测试与其他资源文件。需要完整目录树骨架时加 --full(§2 子包与 collections/locale/ai 资源目录,纯空目录,内容按需自建)。生成后自动跑 check-rules.py 自检。

人工待办(脚本结束会打印清单):plugin.json 的 displayName/description;集合/动作/ACL/迁移/i18n 等按需自建(全栈写法参照本仓库 plugin-hello-world 范例与 .harness/rules/plugin-rule.md)。

多段命名示例(产品-功能):QMS 产品的 SPC 功能 → new-plugin.py qms-spc 生成 plugin-qms-spc,name @aimom/plugin-qms-spc,包(basePackageDir) com.sie.aimom.plugins.qmsspc。

集成进 aimom-starter

  • 路径 A(主推):Maven 依赖引用随 fat-jar 分发——本仓库交付 jar 后,由平台方在 aimom 主仓库登记两处(根 pom.xml <dependencyManagement> 按字母序登记版本 + aimom-starter/pom.xml <dependencies> 无版本引用,不含插件源码)并重打 starter;依赖由 Maven 正常装配,无 shade 问题
  • 路径 B(备选):外置 JAR 放入外部插件目录(默认 ./plugins,自动加载默认开启),重启进程即被加载并自动启用;注意事项与本地操作见下方「本地启动调试」

本地启动调试(fat jar + ./plugins)

没有 aimom 源码也能本地调试插件:一个 aimom-starter fat jar(约 300MB,由平台组提供;有源码的机器也可在主仓库 mvn -pl aimom-starter -am clean package -DskipTests 自打)+ 本仓库构建的插件 jar,前置 JDK 21,三步跑通。

1. 构建插件并放入 ./plugins/

# 在 starter jar 所在目录执行(./plugins 相对 java 进程工作目录解析,与 aimom-starter.jar 平级)
mvn clean install -pl plugin-hello-world
mkdir -p plugins && cp plugin-hello-world/target/plugin-hello-world-1.0.0-SNAPSHOT.jar plugins/
  • 外部插件自动加载默认开启;./plugins 为唯一外部插件目录,相对 java 进程工作目录解析(目录不存在仅 WARN 跳过)
  • 外置 jar 文件名须符合命名契约(.harness/rules/plugin-rule.md §1)
  • 增删 jar 后需重启进程生效(运行期动态加载 pm:add 未实现)
  • 不要把 starter 已内置的同名插件再放进 ./plugins/——资源重复会触发启动异常
  • 插件用到的第三方依赖必须 shade 进插件 jar(aimom-core 为 provided 不打入);插件模块禁止 spring-boot-maven-plugin

2. 准备外部配置(无内网必做)

starter 内置 yml 的数据源默认指向内网开发库(PostgreSQL 192.168.168.54:5436/aimom_dev_v3,Redis 192.168.168.207:32180)。无内网的开发者必须覆盖为自己的 PostgreSQL/Redis,任选一种方式:

  1. 外部配置文件:jar 内置 spring.config.import 会读取 optional:file:/springboot_config/aimom-starter.yml(文件不存在则跳过)。在该路径放置自备的 aimom-starter.yml,覆盖数据源/Redis 等配置。
    • Windows 注意:file:/springboot_config/... 按当前盘符根目录解析——jar 从 D 盘某目录启动即对应 D:\springboot_config\aimom-starter.yml,从 C 盘启动则是 C:\springboot_config\aimom-starter.yml
    • 也可用启动参数显式指定配置文件位置:java -jar aimom-starter.jar --spring.config.location=file:./aimom-starter.yml
  2. 环境变量覆盖单项:AIMOM_DB_URL / AIMOM_DB_USERNAME / AIMOM_DB_PASSWORD

3. 启动与验证

java -jar aimom-starter.jar                # JDK 21,默认端口 14000
  • 日志同时写入 ${java.io.tmpdir}/aimom-logs/aimom-starter.log(Windows 即 %TEMP%\aimom-logs\aimom-starter.log)
  • local 插件登记后的启用行为随交付 starter 版本不同:新版平台默认登记不启用(aimom.plugin.auto-enable-local=false),需在平台插件管理中手动启用;旧版登记即自动启用。后续启停均经平台端插件管理操作

验证清单:

  • 本仓库 mvn clean install 通过(含契约测试:plugin.json 命名 + 双语 locale key 一致)
  • 路径 A:平台方完成两处引用登记,重打 starter(mvn clean install -pl aimom-starter)通过
  • 启动日志出现 [PLUGIN_DISCOVER] discovered ... plugin-hello-world ... 与 [PM_LOAD] 行(被排除时会打 skip 原因)
  • local 插件已被自动登记并启用
  • REST 冒烟:登录态 GET /api/helloWorlds:stats 返回 {"total": 2, ...}(install() 已种子 2 条)

开发约定

规则正文在 .harness/rules/(命名契约与工程结构、编码、数据访问与事务、i18n、日志、异常、构建与提交),AI 协作约束入口见 AGENTS.md。



Comment