插件 API
插件是 LCGYL Framework 的核心扩展机制。本文档详细介绍插件相关的 API 和开发指南。
核心接口
Plugin 接口
所有插件必须实现 com.lcgyl.core.plugin.Plugin 接口。
java
public interface Plugin {
/**
* 获取插件元数据
*/
PluginMetadata getMetadata();
/**
* 初始化插件
*/
void initialize(PluginContext context) throws PluginException;
/**
* 启动插件
*/
void start() throws PluginException;
/**
* 停止插件
*/
void stop() throws PluginException;
/**
* 销毁插件
*/
void destroy() throws PluginException;
}PluginMetadata
插件元数据使用 Java 21 Record 定义,包含插件的基本信息。
java
public record PluginMetadata(
String id, // 插件唯一标识
String name, // 插件名称
String version, // 插件版本
String description, // 插件描述
List<String> dependencies // 依赖的其他插件 ID
) {}PluginContext
插件上下文提供与框架交互的能力。
java
public interface PluginContext {
/**
* 获取配置
*/
Configuration getConfiguration();
/**
* 获取 IoC 容器
*/
Container getContainer();
/**
* 获取事件总线
*/
EventBus getEventBus();
/**
* 获取插件管理器
*/
PluginManager getPluginManager();
}生命周期
插件经历以下生命周期阶段:
- 加载 (Loaded):插件类被加载,元数据被读取。
- 初始化 (Initialized):调用
initialize()方法。在此阶段应该:- 读取配置
- 初始化内部组件
- 注册服务到 IoC 容器
- 启动 (Started):调用
start()方法。在此阶段应该:- 启动后台任务
- 建立网络连接
- 开始监听端口
- 注册事件监听器
- 停止 (Stopped):调用
stop()方法。在此阶段应该:- 停止后台任务
- 断开连接
- 停止监听
- 销毁 (Destroyed):调用
destroy()方法。在此阶段应该:- 释放所有资源
- 清理临时文件
开发指南
1. 定义元数据
java
public class MyPlugin implements Plugin {
private static final PluginMetadata METADATA = new PluginMetadata(
"my-plugin",
"My Plugin",
"1.0.0",
"A demo plugin",
List.of()
);
@Override
public PluginMetadata getMetadata() {
return METADATA;
}
// ...
}2. 实现初始化逻辑
java
@Override
public void initialize(PluginContext context) throws PluginException {
// 获取配置
Configuration config = context.getConfiguration();
String myConfig = config.get("my.config", String.class, "default");
// 注册组件
Container container = context.getContainer();
container.register(MyService.class);
}3. 实现启动逻辑
java
@Override
public void start() throws PluginException {
// 启动服务
MyService service = context.getContainer().getBean(MyService.class);
service.start();
// 注册事件监听
EventBus eventBus = context.getEventBus();
eventBus.subscribe(MyEvent.class, this::onMyEvent);
}4. 异常处理
如果生命周期方法抛出 PluginException,框架会中断启动流程并报告错误。
java
@Override
public void start() throws PluginException {
try {
server.start();
} catch (IOException e) {
throw new PluginException("Failed to start server", e);
}
}最佳实践
- 依赖管理:在元数据中明确声明依赖,框架会确保依赖的插件先启动。
- 资源释放:确保在
stop()和destroy()中释放所有占用的资源(线程池、连接、文件句柄等)。 - 无状态:尽量让插件类本身保持无状态,将状态委托给 IoC 容器中的组件管理。
- 配置命名空间:插件配置应该使用统一的前缀,如
plugin.{id}.xxx,避免冲突。