Skip to content

Commit 117cf8f

Browse files
committed
docs(plugin): 更新插件开发文档以匹配新架构
- 将插件启动流程图替换为 Mermaid 序列图,详细展示加载、排序和安装过程 - 修改代码示例中的类路径从 org.smartboot.mqtt.broker.plugin.Plugin 到 tech.smartboot.mqtt.plugin.spec.Plugin - 更新依赖版本从 1.4.0 到 1.5.0 - 替换 install/uninstall 方法说明为 initPlugin/destroyPlugin 方法 - 添加插件配置章节,介绍通过 plugin.yaml 文件进行配置的方法 - 增加集群插件和企业版插件的参考示例 - 更新最佳实践指南,强调新的方法调用和版本管理要求
1 parent b52cd96 commit 117cf8f

1 file changed

Lines changed: 106 additions & 27 deletions

File tree

pages/src/content/docs/development/plugin.mdx

Lines changed: 106 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,44 @@ smart-mqtt 企业版的几乎每项特性都是一个插件,并且插件与插
2424

2525
插件,在 smart-mqtt 中的侵入性是非常低的。如果结合代码的话,你应该能在几分钟内完全掌握它的精髓。
2626

27-
![插件启动流程](./img/plugin_start.png)
27+
```mermaid
28+
sequenceDiagram
29+
participant Broker as Broker启动器
30+
participant SL as ServiceLoader
31+
participant Plugins as 插件集合
32+
participant P as 具体插件
33+
34+
Broker->>SL: 加载 classpath 中的所有插件
35+
SL->>Plugins: 发现并注册插件实例
36+
loop 按优先级排序
37+
Broker->>Plugins: 获取插件列表
38+
Plugins-->>Broker: 返回排序后的插件
39+
end
40+
loop 依次安装
41+
Broker->>P: 调用 install(context)
42+
P->>P: 执行 initPlugin()<br/>插件初始化逻辑
43+
P-->>Broker: 安装完成
44+
end
45+
Broker->>Broker: 启动 Broker 服务
46+
```
2847

2948
上图为 smart-mqtt 服务启动的完整流程,插件处于其中间环节。插件的启动分为两个步骤:
3049

3150
1. 通过 `ServiceLoader` 的方式加载 `classpath` 内的所有插件实例
3251
2. 按插件的优先级进行排序,再执行 `install` 方法安装启用插件
3352

3453
```java
35-
private void loadAndInstallPlugins() {
36-
for (Plugin plugin : ServiceLoader.load(Plugin.class, Providers.class.getClassLoader())) {
37-
LOGGER.info("load plugin: " + plugin.pluginName());
54+
private void loadAndInstallPlugins() throws Throwable {
55+
for (Plugin plugin : ServiceLoader.load(Plugin.class, BrokerContextImpl.class.getClassLoader())) {
56+
System.out.println("load plugin: " + plugin.pluginName());
3857
plugins.add(plugin);
3958
}
4059
// 安装插件
41-
plugins.stream().sorted(Comparator.comparingInt(Plugin::order)).forEach(plugin -> {
42-
LOGGER.info("install plugin: " + plugin.pluginName());
60+
plugins.sort(Comparator.comparingInt(Plugin::order));
61+
for (Plugin plugin : plugins) {
62+
System.out.println("install plugin: " + plugin.pluginName());
4363
plugin.install(this);
44-
});
64+
}
4565
}
4666
```
4767

@@ -53,9 +73,23 @@ private void loadAndInstallPlugins() {
5373

5474
卸载插件,是 smart-mqtt Broker 停止服务的一个必经过程,以此保证服务的优雅退出和资源的充分释放。
5575

56-
![插件退出流程](./img/plugin_stop.png)
76+
```mermaid
77+
sequenceDiagram
78+
participant Broker as Broker容器
79+
participant Plugins as 插件列表
80+
participant P as 具体插件
81+
82+
Broker->>Broker: 停止接收新连接
83+
loop 逆序遍历卸载
84+
Broker->>P: 调用 uninstall()
85+
P->>P: 执行 destroyPlugin()<br/>资源释放逻辑
86+
P-->>Broker: 卸载完成
87+
end
88+
Broker->>Plugins: clear()
89+
Broker->>Broker: 销毁 Broker 服务
90+
```
5791

58-
实现的代码也仅仅只有2行
92+
实现的代码如下
5993

6094
```java
6195
plugins.forEach(Plugin::uninstall);
@@ -79,7 +113,7 @@ plugins.clear();
79113
<dependency>
80114
<groupId>org.smartboot.mqtt</groupId>
81115
<artifactId>smart-mqtt-broker</artifactId>
82-
<version>1.4.0</version>
116+
<version>1.5.0</version>
83117
</dependency>
84118
</dependencies>
85119

@@ -109,7 +143,7 @@ plugins.clear();
109143
<transformers>
110144
<!-- 采用追加的方式 -->
111145
<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
112-
<resource>META-INF/services/org.smartboot.mqtt.broker.plugin.Plugin</resource>
146+
<resource>META-INF/services/tech.smartboot.mqtt.plugin.spec.Plugin</resource>
113147
</transformer>
114148
</transformers>
115149
</configuration>
@@ -126,7 +160,7 @@ plugins.clear();
126160

127161
### 3. 编写插件代码
128162

129-
`resources/META-INF/services` 目录下创建名为 `org.smartboot.mqtt.broker.plugin.Plugin` 的文件,内容为插件实现类的全限定名。
163+
`resources/META-INF/services` 目录下创建名为 `tech.smartboot.mqtt.plugin.spec.Plugin` 的文件,内容为插件实现类的全限定名。
130164

131165
```
132166
tech.smartboot.mqtt.plugin.demo.DemoPlugin
@@ -137,30 +171,41 @@ tech.smartboot.mqtt.plugin.demo.DemoPlugin
137171
```java
138172
package tech.smartboot.mqtt.plugin.demo;
139173

140-
import org.smartboot.mqtt.broker.BrokerContext;
141-
import org.smartboot.mqtt.broker.plugin.Plugin;
174+
import tech.smartboot.mqtt.plugin.spec.BrokerContext;
175+
import tech.smartboot.mqtt.plugin.spec.Options;
176+
import tech.smartboot.mqtt.plugin.spec.Plugin;
142177

143178
public class DemoPlugin extends Plugin {
144-
179+
145180
@Override
146-
public void install(BrokerContext brokerContext) {
147-
System.out.println("DemoPlugin installed!");
181+
protected void initPlugin(BrokerContext brokerContext) throws Throwable {
182+
System.out.println("DemoPlugin initialized!");
148183
// 在这里编写插件初始化逻辑
149184
// 例如:订阅事件、注册服务、启动线程等
150185
}
151-
186+
152187
@Override
153-
public void uninstall() {
154-
System.out.println("DemoPlugin uninstalled!");
188+
protected void destroyPlugin() {
189+
System.out.println("DemoPlugin destroyed!");
155190
// 在这里编写插件卸载逻辑
156191
// 例如:释放资源、停止线程等
157192
}
158-
193+
159194
@Override
160195
public String pluginName() {
161196
return "DemoPlugin";
162197
}
163-
198+
199+
@Override
200+
public String getVersion() {
201+
return "1.0.0";
202+
}
203+
204+
@Override
205+
public String getVendor() {
206+
return "Your Company";
207+
}
208+
164209
@Override
165210
public int order() {
166211
// 插件加载顺序,值越小优先级越高
@@ -169,6 +214,12 @@ public class DemoPlugin extends Plugin {
169214
}
170215
```
171216

217+
:::tip[提示]
218+
- `install()``uninstall()` 方法是 `final` 的,子类不能重写。
219+
- 需要在 `initPlugin()` 中编写初始化逻辑,在 `destroyPlugin()` 中编写资源释放逻辑。
220+
- `getVersion()``getVendor()` 是抽象方法,必须实现。
221+
:::
222+
172223
### 4. 打包与部署
173224

174225
运行 `mvn clean package` 打包插件,将生成的 jar 文件放入 smart-mqtt 的 `plugins` 目录下,重启服务即可生效。
@@ -181,7 +232,7 @@ public class DemoPlugin extends Plugin {
181232

182233
```java
183234
@Override
184-
public void install(BrokerContext brokerContext) {
235+
protected void initPlugin(BrokerContext brokerContext) {
185236
brokerContext.getProviders().setAuthenticationValidator((client, username, password) -> {
186237
// 自定义认证逻辑
187238
return "admin".equals(username) && "123456".equals(password);
@@ -195,7 +246,7 @@ public void install(BrokerContext brokerContext) {
195246

196247
```java
197248
@Override
198-
public void install(BrokerContext brokerContext) {
249+
protected void initPlugin(BrokerContext brokerContext) {
199250
// 订阅消息接收事件
200251
brokerContext.getEventBus().subscribe(EventType.RECEIVE_PUBLISH_MESSAGE, event -> {
201252
MqttPublishMessage message = event.getObject();
@@ -210,7 +261,7 @@ public void install(BrokerContext brokerContext) {
210261

211262
```java
212263
@Override
213-
public void install(BrokerContext brokerContext) {
264+
protected void initPlugin(BrokerContext brokerContext) {
214265
// 定时上报指标
215266
ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();
216267
scheduler.scheduleAtFixedRate(() -> {
@@ -219,13 +270,39 @@ public void install(BrokerContext brokerContext) {
219270
}
220271
```
221272

273+
## 插件配置
274+
275+
插件支持通过 `plugin.yaml` 文件进行配置,放置在插件的存储目录中。
276+
277+
```java
278+
@Override
279+
protected void initPlugin(BrokerContext brokerContext) throws Throwable {
280+
// 加载插件配置
281+
PluginConfig config = loadPluginConfig(PluginConfig.class);
282+
if (config != null) {
283+
System.out.println("Server URL: " + config.getServerUrl());
284+
}
285+
}
286+
```
287+
288+
配置类定义:
289+
290+
```java
291+
public class PluginConfig {
292+
private String serverUrl;
293+
private int timeout;
294+
// getter/setter
295+
}
296+
```
297+
222298
## 最佳实践
223299

224300
1. **插件职责单一**:每个插件只负责一个明确的功能
225301
2. **正确处理异常**:插件中的异常不应影响 Broker 的正常运行
226-
3. **资源及时释放**:在 `uninstall` 方法中释放所有资源
302+
3. **资源及时释放**:在 `destroyPlugin()` 方法中释放所有资源
227303
4. **配置外部化**:将可变参数提取到配置文件中
228304
5. **日志规范**:使用统一的日志框架,避免直接打印到控制台
305+
6. **版本管理**:合理实现 `getVersion()` 方法,便于插件版本追踪
229306

230307
## 参考插件
231308

@@ -235,5 +312,7 @@ smart-mqtt 官方提供了多个参考插件:
235312
- **redis-bridge-plugin**:MQTT 消息与 Redis 集成
236313
- **websocket-plugin**:WebSocket 连接支持
237314
- **memory-session-plugin**:内存会话状态管理
315+
- **cluster-plugin**:集群功能支持
316+
- **enterprise-plugin**:企业版功能插件
238317

239-
你可以在 [Gitee 仓库](https://gitee.com/smartboot/smart-mqtt/tree/master/plugins) 查看这些插件的源码。
318+
你可以在 [Gitee 仓库](https://gitee.com/smartboot/smart-mqtt/tree/master/plugins) 查看这些插件的源码。

0 commit comments

Comments
 (0)