Skip to content

插件 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();
}

生命周期

插件经历以下生命周期阶段:

  1. 加载 (Loaded):插件类被加载,元数据被读取。
  2. 初始化 (Initialized):调用 initialize() 方法。在此阶段应该:
    • 读取配置
    • 初始化内部组件
    • 注册服务到 IoC 容器
  3. 启动 (Started):调用 start() 方法。在此阶段应该:
    • 启动后台任务
    • 建立网络连接
    • 开始监听端口
    • 注册事件监听器
  4. 停止 (Stopped):调用 stop() 方法。在此阶段应该:
    • 停止后台任务
    • 断开连接
    • 停止监听
  5. 销毁 (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);
    }
}

最佳实践

  1. 依赖管理:在元数据中明确声明依赖,框架会确保依赖的插件先启动。
  2. 资源释放:确保在 stop()destroy() 中释放所有占用的资源(线程池、连接、文件句柄等)。
  3. 无状态:尽量让插件类本身保持无状态,将状态委托给 IoC 容器中的组件管理。
  4. 配置命名空间:插件配置应该使用统一的前缀,如 plugin.{id}.xxx,避免冲突。

Released under the Apache License 2.0