3、源码获取与项目结构解析:从GitHub克隆ThingsBoard源码、IDE导入、项目模块划分、核心包依赖关系

好,咱们进入实战环节的第一步——把ThingsBoard的源码搞到手,然后看看它到底长什么样。

说实话,我第一次接触ThingsBoard源码时,也被它的模块数量吓了一跳。但别担心,理清了结构,你会发现它其实很清晰。

3.1 从GitHub克隆源码

先说说怎么把代码拉下来。我个人习惯用SSH方式,省得每次输密码。

git clone git@github.com:thingsboard/thingsboard.git
cd thingsboard
git checkout v3.5.1  # 建议选一个稳定版本

嗯,这里要注意:千万别直接拉master分支。我在项目中吃过这个亏——master分支可能正在开发新功能,编译时各种报错。建议选一个release版本,比如v3.5.1或v3.6.0。

避坑指南:我曾经因为拉错了分支,折腾了两天才发现是版本问题。建议先看看项目的Release页面,选一个最新的稳定版。

3.2 IDE导入(IntelliJ IDEA推荐)

我个人强烈推荐IntelliJ IDEA。为什么?因为ThingsBoard是Java项目,IDEA对Maven多模块项目的支持是最好的。

导入步骤很简单:

  1. 打开IDEA,选择 File → New → Project from Existing Sources
  2. 选中你刚才克隆的 thingsboard 目录
  3. 选择 Import project from external model → Maven
  4. 勾选 Search for projects recursively
  5. 一路Next,等它下载依赖

这里有个小技巧:第一次导入时,IDEA会下载大量Maven依赖。你想想看,光是Spring Boot的依赖就有上百个。建议用阿里云的Maven镜像,速度能快10倍。

// 在 ~/.m2/settings.xml 中配置
<mirror>
  <id>aliyunmaven</id>
  <mirrorOf>*</mirrorOf>
  <name>阿里云公共仓库</name>
  <url>https://maven.aliyun.com/repository/public</url>
</mirror>
提示:导入完成后,IDEA右下角会显示索引进度。别急,等它跑完。我一般趁这个时间去泡杯咖啡。

3.3 项目模块划分

ThingsBoard的模块划分,说白了就是一套微服务架构的经典拆分。咱们来看看核心模块:

模块名 作用 我眼中的重要性
application 主启动模块,包含REST API、WebSocket等 ⭐⭐⭐⭐⭐ 入口,必须了解
dao 数据访问层,封装了数据库操作 ⭐⭐⭐⭐ 二次开发常改
rule-engine 规则引擎,处理设备数据的流转 ⭐⭐⭐⭐ 核心业务逻辑
transport 传输层,支持MQTT、HTTP、CoAP等协议 ⭐⭐⭐⭐ 设备接入的关键
common 公共工具类、常量定义 ⭐⭐⭐ 到处都在用
ui-ngx 前端Angular项目 ⭐⭐⭐ 改界面时用

你可能会问:为什么要把transport单独拆出来?

其实原因很简单——不同的设备用不同的协议。MQTT设备、HTTP设备、CoAP设备,它们的接入逻辑完全不同。拆开之后,你可以单独修改某个协议的实现,不影响其他协议。

重点:二次开发时,80%的改动集中在 applicationdaorule-engine 这三个模块。其他模块一般不动。

3.4 核心包依赖关系

模块之间的依赖关系,我画个简图给你看:

application
  ├── dao
  ├── rule-engine
  ├── transport
  └── common

dao
  └── common

rule-engine
  ├── dao
  └── common

transport
  ├── dao
  └── common

看到了吗?common 模块是所有模块的基石。它里面放了什么?

  • 数据模型(Device、Asset等实体类)
  • 工具类(JSON解析、日期处理)
  • 常量定义(API路径、错误码)
  • 异常类(自定义业务异常)

我记得有一次,我想在规则引擎里调用一个数据库查询方法。结果发现 rule-engine 依赖了 dao,而 dao 又依赖了 common。这个依赖链是单向的,不能反过来。所以如果你在 common 里想用 dao 的东西,那就会形成循环依赖——IDEA会直接报错。

注意:循环依赖是Maven多模块项目的大忌。我见过有人硬塞代码导致循环依赖,最后整个项目编译不过。记住:依赖方向永远是 application → 其他模块 → common

3.5 实际开发中的模块选择

如果你只是做简单的二次开发,比如改个设备属性、加个API接口,那只需要关注 applicationdao 就够了。

但如果你想做深度的定制,比如:

  • 新增一种设备协议 → 改 transport
  • 修改数据流转逻辑 → 改 rule-engine
  • 增加新的数据模型 → 改 daocommon

我个人建议:刚开始别贪多,先从一个模块入手。我当年就是从 application 模块的REST API开始改起的,慢慢才扩展到其他模块。

小技巧:在IDEA里,你可以用 Ctrl+Shift+F 全局搜索,快速定位某个类或方法在哪个模块。比如搜 DeviceService,就能看到它在 dao 模块里。

好了,源码获取和项目结构就讲到这里。下一章咱们开始动手编译和运行,到时候你会看到这些模块是怎么协作的。