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-starterAuto Configuration / YAML / Bean Wiringmqtt-plus-springAnnotation Scan / Method Binding / Spring Eventsmqtt-plus-coreRouter / Registry / SPI / Subscription / Error Handlingmqtt-plus-pahoPaho Adaptermqtt-plus-spring-integrationSpring Integration Adaptermqtt-plus-testTest Template / Embedded Brokermqtt-plus-samplesSample Applications这张图里最关键的是三层关系mqtt-plus-core是稳定内核定义路由、注册、SPI、订阅协调和错误处理等核心能力。mqtt-plus-paho与mqtt-plus-spring-integration是并列的 adapter 实现层它们依赖 core但不会反过来影响 core 的接口边界。mqtt-plus-spring与mqtt-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-springMqttListener扫描、方法参数解析、Spring 事件桥接mqtt-plus-spring-boot-starterYAML 配置绑定、条件装配、adapter 选择与默认 Bean 注册mqtt-plus-test测试模板、embedded broker、测试场景支撑mqtt-plus-samples示例工程用来验证从配置到运行链路的可用性如果只看名字这像是“把工程拆成了几个 jar”但如果从依赖方向看它其实是在回答一个很具体的问题哪些能力必须稳定哪些能力应该可替换哪些能力只属于某个生态层。四、三个核心设计原则如果只看模块列表很容易把 mqtt-plus 理解成“把工程拆成几个 jar”。但真正决定这些模块边界的不是目录习惯而是几条设计原则。模块拆分只是结果原则才是原因。原则 1core 零框架依赖mqtt-plus-core不依赖 Spring / Paho / Jackson原则 2adapter 可插拔mqtt-plus-pahomqtt-plus-spring-integration原则 3Spring 层只做粘合mqtt-plus-springmqtt-plus-spring-boot-starter1. core 零框架依赖mqtt-plus-core的职责是定义框架真正稳定的部分比如MqttClientAdapter、MqttListenerRegistry、路由器、订阅协调器和错误处理抽象。只要这层边界稳定上层无论是换 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-plusspring-integration-mqttraw 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 的拆分本质上是在区分稳定内核、可替换实现和生态集成。MqttClientAdapter、MqttListenerRegistry、mqtt-plus-core、mqtt-plus-spring-boot-starter这些组件之所以重要不是因为它们名字显眼而是因为它们正好落在架构边界上。整个系列后面讲的消息路由、序列化、错误处理、多 broker 和自动装配其实都建立在这一层分层哲学之上。下一篇会进入整个框架最核心的一条运行链路一条 MQTT 消息到底如何走到MqttListener。系列导航本文是mqtt-plus 架构解析系列的第 1/10 篇。#主题链接1总览分层架构与设计哲学本文2消息路由一条 MQTT 消息如何到达你的MqttListener待更新3Payload 序列化与反序列化双链设计的取舍待更新4拦截器链MqttMessageInterceptor的扩展点设计待更新5错误处理ErrorAction聚合策略的设计逻辑待更新6多 Broker 管理如何让一个应用同时连接多个 MQTT 服务待更新7动态订阅与重连恢复Reconciler的协调机制待更新8Spring Boot 自动装配零件是怎么被粘合起来的待更新9测试体系MqttTestTemplate与EmbeddedBroker的设计待更新10从内部项目到开源框架mqtt-plus 的抽取过程与决策待更新上一篇无下一篇消息路由一条 MQTT 消息如何到达你的MqttListener待更新链接