mqtt-plus 架构解析(一):分层架构与设计哲学

mqtt-plus 架构解析(一):分层架构与设计哲学

摘要

mqtt-plus 是一个面向 Java / Spring Boot 的 MQTT 框架,但它的 core 层既不依赖 Spring,也不依赖具体 MQTT 客户端。本文是架构解析系列的第 1 篇,不讲 API 用法,而是先回答一个更底层的问题:为什么 mqtt-plus 要拆成 6 个模块,以及这些模块边界背后到底遵循了什么设计原则。


在很多项目里,MQTT 一开始只是"把消息收进来、再把消息发出去"的通信组件。但只要系统开始涉及多 broker、动态订阅、断线重连、注解驱动监听和统一测试支持,问题很快就会从"会不会用客户端"变成"这些能力应该放在哪一层"。

mqtt-plus 的价值,不只是把几种能力凑在一起,而是试图把这些能力组织成一套边界清晰、可扩展、可测试的工程结构。也正因为如此,这个系列不打算先讲功能点,而是先讲分层逻辑。


一、这篇文章到底想回答什么?

这篇总览篇不打算展开所有实现细节,它只回答三个问题:

  • 为什么 mqtt-plus 要拆成 6 个模块,而不是做成一个"大而全"的 jar
  • 为什么 mqtt-plus-core 必须保持对 Spring 和具体 MQTT 客户端零依赖
  • 为什么这样的分层,能够支撑后面的消息路由、序列化、错误处理、多 broker 和自动装配设计

如果只记住一句话,那就是:

mqtt-plus 的模块拆分不是为了"项目结构好看",而是为了把稳定内核、可替换实现和集成层边界真正分开。

后面的系列文章会沿着这条主线逐步展开。第 1 篇先讲清"为什么这样分层",第 2 篇再进入最核心的运行问题:一条 MQTT 消息到底是如何到达 @MqttListener 的。


二、mqtt-plus 从哪里来

mqtt-plus 的前身并不是一个从零开始的"理想化开源项目",而是从内部项目 drone-framework 中逐步抽出来的。那个阶段里,项目里已经有 4 个 MQTT 相关模块,分别承担不同场景下的连接、监听和桥接逻辑。

问题在于,这 4 个模块做的很多事情本质上高度重合:都要管 broker 连接,都要处理监听方法,都要面对订阅恢复和消息分发。模块一多,重复实现就多;一旦要修一个 bug,常常意味着在多个地方同步修补。

更麻烦的是,这些实现和 Spring 绑定得很深。它们当然能在原项目里工作,但很难把真正通用的那部分能力单独提炼出来,更难在非 Spring 场景里复用。也就是说,问题不只是"代码有重复",而是"边界没立住"。

所以 mqtt-plus 这次没有选择直接把旧代码搬到新仓库,而是反过来先问一个问题:哪些能力应该沉到稳定内核里,哪些能力应该留在 Spring 集成层,哪些能力应该作为 adapter 存在。这才有了今天的模块拆分。


三、模块全景

先不要急着看每个模块的职责,先看整体分层关系。对理解 mqtt-plus 来说,最重要的不是记住模块名字,而是先搞清楚哪一层是稳定内核,哪一层是实现适配,哪一层是 Spring 生态的集成与装配。
mqtt-plus-spring-boot-starter

Auto Configuration / YAML / Bean Wiring
mqtt-plus-spring

Annotation Scan / Method Binding / Spring Events
mqtt-plus-core

Router / Registry / SPI / Subscription / Error Handling
mqtt-plus-paho

Paho Adapter
mqtt-plus-spring-integration

Spring Integration Adapter
mqtt-plus-test

Test Template / Embedded Broker
mqtt-plus-samples

Sample Applications

这张图里最关键的是三层关系:

  • mqtt-plus-core 是稳定内核,定义路由、注册、SPI、订阅协调和错误处理等核心能力。
  • mqtt-plus-pahomqtt-plus-spring-integration 是并列的 adapter 实现层,它们依赖 core,但不会反过来影响 core 的接口边界。
  • mqtt-plus-springmqtt-plus-spring-boot-starter 是面向 Spring 生态的粘合与装配层,负责把核心能力接到开发者熟悉的使用方式上。

从模块职责上看,可以再压缩成下面这个表:

模块 主要职责
mqtt-plus-core 路由引擎、listener 注册、topic 匹配、SPI、订阅协调、错误处理
mqtt-plus-paho 基于 Eclipse Paho 的 adapter 实现
mqtt-plus-spring-integration 基于 Spring Integration MQTT 的 adapter 实现
mqtt-plus-spring @MqttListener 扫描、方法参数解析、Spring 事件桥接
mqtt-plus-spring-boot-starter YAML 配置绑定、条件装配、adapter 选择与默认 Bean 注册
mqtt-plus-test 测试模板、embedded broker、测试场景支撑
mqtt-plus-samples 示例工程,用来验证从配置到运行链路的可用性

如果只看名字,这像是"把工程拆成了几个 jar";但如果从依赖方向看,它其实是在回答一个很具体的问题:哪些能力必须稳定,哪些能力应该可替换,哪些能力只属于某个生态层。


四、三个核心设计原则

如果只看模块列表,很容易把 mqtt-plus 理解成"把工程拆成几个 jar"。但真正决定这些模块边界的,不是目录习惯,而是几条设计原则。模块拆分只是结果,原则才是原因。
原则 1

core 零框架依赖
mqtt-plus-core

不依赖 Spring / Paho / Jackson
原则 2

adapter 可插拔
mqtt-plus-paho
mqtt-plus-spring-integration
原则 3

Spring 层只做粘合
mqtt-plus-spring
mqtt-plus-spring-boot-starter

1. core 零框架依赖

mqtt-plus-core 的职责是定义框架真正稳定的部分,比如 MqttClientAdapterMqttListenerRegistry、路由器、订阅协调器和错误处理抽象。只要这层边界稳定,上层无论是换 adapter,还是换 Spring 的装配方式,都不应该反向改动 core。

这背后的价值不是"纯粹",而是稳定。一个框架真正容易演进的前提,不是功能少,而是最核心的抽象不会因为外层实现变化而频繁改口。

设计决策: mqtt-plus-core 不依赖 Spring,也不依赖任何具体 MQTT 客户端。这样做的目的,不是追求"纯粹",而是让消息路由、订阅协调、错误处理这些核心能力保持稳定,并且可以在非 Spring 环境中复用。

2. adapter 可插拔

框架最终总要落到某个 MQTT 客户端实现上,但这个选择不应该写死在核心层里。mqtt-plus 通过 MqttClientAdapter 这一层抽象,把"框架内部如何组织消息"和"具体通过哪个客户端收发消息"解耦开来。

所以你今天可以用 mqtt-plus-paho,明天也可以切到 mqtt-plus-spring-integration;更重要的是,多 broker 场景下,不同 broker 甚至可以绑定不同 adapter,而不需要把整套业务逻辑重写一遍。

设计决策: mqtt-plus 没有做成一个"大而全"的单 jar,而是拆成 core、adapter、spring、starter、test 等模块。模块拆分的重点不是目录整洁,而是把稳定内核、实现差异和生态集成边界真正隔离开。

3. Spring 层只做粘合

在很多项目里,Spring 一旦介入,就容易从"集成层"变成"核心层",最后所有抽象都不自觉地长成 Spring 风格。mqtt-plus 刻意避免了这件事。

mqtt-plus-spring 做的是把 @MqttListener、方法参数解析、事件发布这些 Spring 友好能力接到 core 上;mqtt-plus-spring-boot-starter 做的是读取配置、条件注册 Bean、选择默认 adapter。换句话说,它们负责的是"更好用",不是"定义核心语义"。

这样的好处是,Spring 生态体验可以继续迭代,但不会把整个框架拖成"只有 Spring Boot 才能完整运行"的结构。


五、和现有方案的定位差异

在 Java 生态里,做 MQTT 接入最常见的两种方式,一种是直接使用 raw Paho,另一种是基于 spring-integration-mqtt。mqtt-plus 和它们不是简单的替代关系,而是处在不同抽象层级上。

维度 mqtt-plus spring-integration-mqtt raw Paho
面向层级 工程级框架层 Spring 集成组件层 客户端库层
多 broker 管理 内置统一模型 需要自己组装多套 Bean 需要自己管理多实例 client
注解驱动监听 无直接等价模型
动态订阅 + 恢复 有统一协调机制 需要自行补齐 需要自行补齐
adapter 可插拔 基本绑定自身实现 基本绑定自身实现
非 Spring 场景 core + adapter 可独立运行 不适合 可以
测试支撑 mqtt-plus-test 无统一方案 无统一方案

所以更准确的理解应该是:Paho 和 Spring Integration 解决的是"怎么和 broker 通信",mqtt-plus 解决的是"在项目里怎么把 MQTT 相关能力组织得更像一个框架,而不是一堆零散客户端代码"。

这也是为什么 mqtt-plus 的 adapter 层不是要"替代"这些客户端,而是要把它们纳入统一的框架边界里。


六、小结

这一篇文章回答的不是"mqtt-plus 有哪些功能",而是"为什么它会长成现在这个样子"。

可以把结论压缩成四句话:

  • mqtt-plus 不是从零拍脑袋设计出来的,而是从内部项目的重复能力和边界问题里抽出来的。
  • mqtt-plus-core、adapter、Spring 层、starter 和 test 的拆分,本质上是在区分稳定内核、可替换实现和生态集成。
  • MqttClientAdapterMqttListenerRegistrymqtt-plus-coremqtt-plus-spring-boot-starter 这些组件之所以重要,不是因为它们名字显眼,而是因为它们正好落在架构边界上。
  • 整个系列后面讲的消息路由、序列化、错误处理、多 broker 和自动装配,其实都建立在这一层分层哲学之上。

下一篇会进入整个框架最核心的一条运行链路:一条 MQTT 消息到底如何走到 @MqttListener


系列导航

本文是 mqtt-plus 架构解析 系列的第 1/10 篇。

# 主题 链接
1 总览:分层架构与设计哲学 本文
2 消息路由:一条 MQTT 消息如何到达你的 @MqttListener 待更新
3 Payload 序列化与反序列化:双链设计的取舍 待更新
4 拦截器链:MqttMessageInterceptor 的扩展点设计 待更新
5 错误处理:ErrorAction 聚合策略的设计逻辑 待更新
6 多 Broker 管理:如何让一个应用同时连接多个 MQTT 服务 待更新
7 动态订阅与重连恢复:Reconciler 的协调机制 待更新
8 Spring Boot 自动装配:零件是怎么被粘合起来的 待更新
9 测试体系:MqttTestTemplateEmbeddedBroker 的设计 待更新
10 从内部项目到开源框架:mqtt-plus 的抽取过程与决策 待更新

上一篇:无

下一篇:消息路由:一条 MQTT 消息如何到达你的 @MqttListener(待更新链接)

相关推荐
DolphinDB智臾科技2 小时前
基于外部表的物联网多源数据融合与联合查询实践
物联网
147API2 小时前
Claude 在多模型架构里的定位分析
人工智能·架构·claude·大模型api
zhou lily2 小时前
HA高可用性架构:保障数字化转型业务连续性的关键
架构
猫头虎-人工智能2 小时前
ToDesk ToClaw AI自动化实测:零门槛玩转日常自动化,告别折腾与硬件损耗
运维·人工智能·架构·开源·自动化·aigc·ai编程
乾元2 小时前
《硅基之盾》番外篇一:时间的折叠——AI 时代下的物理隔离与传统工控(ICS/OT)安全
网络·人工智能·安全·网络安全·架构
AEIC学术交流中心2 小时前
【快速EI检索 | SPIE出版】2026年物联网、通信工程与人工智能国际学术会议(IoTCEAI 2026)
人工智能·物联网
深念Y2 小时前
Harness Engineering:我的HomeSense Agent 架构演进
人工智能·算法·架构·智能家居·agent·小爱同学·harness
海兰2 小时前
【springboot】gradle快速镜像配置
spring boot·笔记·后端
武超杰2 小时前
SpringBoot 整合 Spring Security 实现权限控制
spring boot·后端·spring