JeecgBoot 后端架构与技术栈全景导读 01

项目定位 :AI 低代码平台,前后端分离,后端是 Spring Boot 3 / Spring Cloud Alibaba。

技术栈主线 :JDK 17、Spring Boot 3.5.5、Spring Cloud 2025、Spring Cloud Alibaba、MyBatis-Plus、Shiro、JWT、Druid、Nacos、Gateway。

模块结构 :

  • jeecg-boot-base-core :公共核心能力、配置、工具类、安全、MyBatis、Shiro。

  • jeecg-module-system :系统业务模块,包含 API、业务实现、单体启动。

  • jeecg-boot-module :扩展业务模块,如 demo、AI RAG。

  • jeecg-server-cloud :微服务版本,包含 Gateway、Nacos、Cloud Start、监控等。

项目定位

JeecgBoot 是一个 企业级 AI 低代码开发平台 。

核心特点:

  • 基于 Spring Boot 3

  • 支持 Spring Cloud Alibaba 微服务架构

  • 使用 MyBatis-Plus 做持久层

  • 使用 Shiro + JWT 做认证授权

  • 支持代码生成、在线表单、报表、大屏、流程、AI 应用、RAG 知识库等能力

技术栈

技术 作用
JDK 17 Java 基础运行版本
Spring Boot 3.5.5 后端应用基础框架
Spring Cloud 2025.0.0 微服务体系
Spring Cloud Alibaba 整合 Nacos、Sentinel 等阿里微服务组件
MyBatis-Plus ORM / DAO 增强
Druid 数据库连接池、SQL 监控
Shiro 权限认证框架
JWT 无状态 Token 登录
Fastjson JSON 数据处理
Knife4j / Swagger 在线接口文档
MinIO / OSS 文件对象存储
XXL-JOB 分布式任务调度
Nacos 注册中心、配置中心
Gateway 微服务网关
Sentinel 流量控制、熔断降级
JimuReport 积木报表、数据大屏能力

maven多模块

版本管理

Maven 多模块项目通常由一个父工程管理多个子模块。

以当前项目为例,根工程是:

核心特点:

  • 父工程通常是 pom 打包方式。

  • 父工程不直接写业务代码,主要负责统一管理。

  • 子模块通过 <modules> 被父工程聚合。

  • 子模块可以继承父 POM 的版本、插件、依赖管理配置。

  • 多模块适合大型项目拆分,例如公共模块、业务模块、启动模块、微服务模块。

    复制代码
    <modules>
          <module>jeecg-boot-base-core</module>
          <module>jeecg-module-system</module>
    	<module>jeecg-boot-module</module>
      </modules>


    复制代码
          <!-- 管理 Spring Cloud 全家桶的版本 -->
          <dependency>
              <groupId>org.springframework.cloud</groupId>
              <artifactId>spring-cloud-dependencies</artifactId>
              <version>${spring-cloud.version}</version>
              
              <type>pom</type>    <!-- 这是一个版本清单文件 -->
              <scope>import</scope> <!-- 把这个版本清单导入进来 -->
          </dependency>
    
      </dependencies>
  • <properties> = 存数字的「变量盒子」**
  • <dependencyManagement> = 用这些数字去 「锁版本」的工具
标签 作用 能不能单独锁版本?
<properties> 定义变量,存版本号数字 ❌ 不能
<dependencyManagement> 统一管理、锁定依赖版本 ✅ 能
  • parent-project
    ├── pom.xml
    ├── common-module
    ├── system-module
    ├── business-module
    └── start-module
聚合和继承

Maven 多模块里最容易混淆的是:

  • 聚合

    module-a module-b

作用:

  • 让父工程一次性构建多个子模块。

  • 控制构建顺序。

  • 常用于根 POM。

  • 聚合关系主要影响"构建"。

一句话:

聚合解决的是"我一次构建哪些模块"。

  • 继承

<parent>

<groupId>xxx</groupId>

<artifactId>parent</artifactId>

<version>1.0.0</version>

</parent>

作用:

  • 子模块继承父 POM 的配置。

  • 可以继承依赖版本、插件版本、属性、仓库、编码配置等。

  • 继承关系主要影响"配置复用"。

一句话:

继承解决的是"我复用谁的配置"。

父工程

├── 作为聚合器:modules 管理子模块

└── 作为父 POM:parent 被子模块继承

但它们不是一回事。

一个模块可以:

  • 被某个 POM 聚合,但不继承它。

  • 继承某个父 POM,但不被它聚合。

  • 既被聚合,又继承父 POM。

多继承

严格来说:

Maven 不支持真正意义上的多继承。

一个 pom.xml 只能有一个 <parent> 。

因为 Maven 可以通过以下方式实现类似效果:

  1. 父 POM 继承祖父 POM。

  2. 当前模块继承父 POM。

  3. 使用 dependencyManagement 导入多个 BOM。

  4. 使用 pluginManagement 管理插件版本。

  5. 使用 profile 做环境配置切换。

Spring Boot Parent

JeecgBoot Parent

子模块

JeecgBoot 根 POM 就继承了 Spring Boot Parent

因此子模块间接获得了 Spring Boot Parent 的部分配置。

依赖管理的特点

<dependencyManagement>

<dependencies>

...

</dependencies>

</dependencyManagement>
例如父 POM 写了:

dependencyManagement>

<dependencies>

<dependency>

<groupId>com.baomidou</groupId>

<artifactId>mybatis-plus-spring-boot3-starter</artifactId>

<version>3.5.12</version>

</dependency>

</dependencies>

</dependencyManagement>

子模块不会自动拥有这个依赖。子模块还需要显式声明:

<dependency>

<groupId>com.baomidou</groupId>

<artifactId>mybatis-plus-spring-boot3-starter</artifactId>

</dependency>

此时可以省略版本号,因为版本由父 POM 管理。

一句话:

dependencyManagement 管版本,不管引入。

dependencies 会直接引入依赖

如果父 POM 直接写:

```

<dependencies>

<dependency>

...

</dependency>

</dependencies>

```

那么子模块通常会继承这些依赖。

所以:

标签 位置 核心作用 特点说明
dependencies 项目根下 / dependencyManagement 直接引入依赖,当前模块 / 子模块生效 声明后立即引入对应 jar 包,所有子模块可直接继承
dependencyManagement 父 POM / 聚合工程根 POM 统一管理依赖版本,不实际引入依赖 仅锁定版本、groupId、artifactId,子模块使用时仍需在 dependencies 声明,无需写版本
pluginManagement 父 POM / 聚合工程根 POM 统一管理插件版本,不实际启用插件 仅锁定插件版本、坐标,子模块需手动声明 plugins 才会生效
plugins 项目根下 / pluginManagement 直接启用并配置插件,当前模块 / 子模块生效 声明后插件立即执行,可绑定生命周期、配置参数,子模块可继承
BOM 的作用

<dependencyManagement>

<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-dependencies</artifactId>

<version>2025.0.0</version>

<type>pom</type>

<scope>import</scope>

</dependency>

</dependencies>

</dependencyManagement>

作用:

  • 批量管理一组依赖版本。

  • 避免每个依赖都手写版本。

  • 保证一整套框架版本兼容。

JeecgBoot 中就导入了:

  • Spring Cloud BOM

  • Spring Cloud Alibaba BOM

一句话:

BOM 是一组依赖版本的清单。

传递依赖

A 依赖 B

B 依赖 C

那么 A 通常也会间接拥有 C。

这就是传递依赖。

优点:

  • 减少重复声明。

  • 框架 starter 可以自动带入所需依赖。

缺点:

  • 容易引入你没意识到的 jar。

  • 容易出现版本冲突。

  • 可能带来安全漏洞。

  • 包体积变大。

Maven 依赖冲突规则

Maven 解决冲突主要有两个规则。

如果同一个依赖出现多个版本:

项目

├── A → C:1.0

└── B → D → C:2.0

Maven 会选 C:1.0 。

因为 C:1.0 离项目更近。

一句话:

谁路径短,谁优先。

路径一样时,先声明优先

如果路径长度一样:

项目

├── A → C:1.0

└── B → C:2.0

如果 A 在 pom.xml 里写在 B 前面,那么优先选择 C:1.0 。

一句话:

路径一样,谁先声明谁优先。

依赖冲突解决
异常名称 含义 最常见原因
ClassNotFoundException 运行时找不到类 依赖没引入、jar 包未下载、打包漏包
NoClassDefFoundError 编译时有,运行时没有 依赖冲突、版本不兼容、类加载失败
NoSuchMethodError 找不到方法(编译通过,运行报错) 依赖版本不一致(运行时版本和编译时不一样)
NoSuchFieldError 找不到字段 依赖版本冲突、类版本不匹配
BeanCreationException Spring 创建 Bean 失败 Spring 组件版本不兼容、配置错误
UnsatisfiedDependencyException Bean 依赖注入失败 依赖缺失、Bean 未被 Spring 管理、循环依赖
排查依赖冲突的方法
  • 看 POM:依赖在哪里声明。

  • 看树:依赖从哪里传进来。

  • 看版本:最终使用哪个版本。

  • 看 scope:运行时是否存在。

  • 看 exclusion:是否误排除了依赖。

  • 看 effective-pom:最终 Maven 配置是什么。

项目单体到微服务转换

项目里有云模式条件类:

JeecgCloudCondition.java

这类配置通常用于判断当前是否启用 Cloud 模式。

效果类似:

如果是单体模式:

加载本地调用相关 Bean

如果是微服务模式:

加载 Cloud / Feign / Nacos 相关 Bean

也就是说:

通过配置条件,决定加载单体 Bean 还是微服务 Bean。

jeecg-boot-base-core

基础

把所有业务模块都会用到的"横切能力"和"基础设施能力"沉淀成一个公共核心包。

它不应该承载具体业务,比如订单、客户、流程审批细节。

它主要解决这些问题:

所有模块怎么统一返回?

所有模块怎么统一异常?

所有模块怎么做登录鉴权?

所有模块怎么做数据权限?

所有模块怎么访问当前登录用户?

所有模块怎么防 SQL 注入?

所有模块怎么做租户隔离?

所有模块怎么统一 Swagger?

所有模块怎么接 OSS / MinIO?

所有模块怎么做字典翻译?

所以它是一个 基础设施层 + 通用能力层 + 横切关注点层 。

启动模块

业务模块

系统 API / 公共 API

base-core

在 JeecgBoot 里:

jeecg-system-start

jeecg-system-cloud-start

jeecg-demo-cloud-start

jeecg-system-biz

jeecg-module-demo

jeecg-boot-base-core

上层业务模块依赖 base-core ,但 base-core 不应该反向依赖具体业务模块。

三个核心包怎么理解

org.jeecg.common

org.jeecg.config

org.jeecg.modules.base

包名 定位 作用
org.jeecg.common 通用模型与工具层 存放返回对象、异常类、常量、DTO、VO、各类工具类
org.jeecg.config 框架配置层 整合 Shiro、MyBatis、Swagger、Druid、WebMvc、OSS、接口签名等配置
org.jeecg.modules.base 基础服务抽象层 提供公共服务接口、通用 Mapper、系统日志等底层基础能力
org.jeecg.common
统一返回结构
java 复制代码
	@Schema(description = "成功标志")
	private boolean success = true;

	/**
	 * 返回处理消息
	 */
	@Schema(description = "返回处理消息")
	private String message = "";

	/**
	 * 返回代码
	 */
	@Schema(description = "返回代码")
	private Integer code = 0;
	
	/**
	 * 返回数据对象 data
	 */
	@Schema(description = "返回数据对象")
	private T result;
	
	/**
	 * 时间戳
	 */
	@Schema(description = "时间戳")
	private long timestamp = System.currentTimeMillis();

不让每个 Controller 自己随便返回数据结构。

code == 200:成功

code == 401:未登录

success == false:失败

message:提示信息

result:业务数据

统一异常处理

@RestControllerAdvice

@Slf4j

public class JeecgBootExceptionHandler

Controller 抛出的异常,统一在这里转换成 Result 返回给前端。

业务代码只负责抛异常,不负责拼错误响应。

常量和枚举

CommonConstant

ServiceNameConstants

TenantConstant

DataBaseConstant

把系统中反复使用的固定值统一收口。

这些的作用是:

把系统中反复使用的固定值统一收口。

比如:

  • HTTP 状态码

  • 服务名

  • 租户字段

  • 数据权限标识

  • 消息类型

  • 文件类型

  • 操作类型

设计原则:

不要让魔法字符串散落在业务代码里。

工具类

JwtUtil

TokenUtils

SpringContextUtils

SqlInjectionUtil

OssBootUtil

MinioUtil

CommonUtils

DateUtils

PasswordUtil

IpUtils

它们解决的是通用操作:

解析 Token

获取 Spring Bean

SQL 注入校验

文件上传

密码加密

日期转换

IP 获取

工具类是方便,但不能滥用。公共层工具类应该只放跨模块都需要的能力。

org.jeecg.config

是 Spring Boot 配置中心。

它把各种框架能力统一装配进项目。

Shiro + JWT 安全配置

请求进来

JwtFilter

解析 token

ShiroRealm 校验用户

判断权限

放行或拒绝

认证鉴权属于横切能力,不应该散落在业务 Controller 里。

业务层只需要写权限注解或调用权限判断。

MyBatis-Plus 与多租户

这里通常处理:

  • MyBatis-Plus 插件

  • 租户隔离

  • 动态表名

  • SQL 拦截

  • 数据权限条件拼接

设计思想:

租户隔离和数据权限尽量下沉到持久层拦截器,而不是每个业务 SQL 手写一遍。

这样业务代码不用到处写:

tenant_id = 当前租户

而是由框架层统一处理。

Swagger / Knife4j 配置

Swagger2Config

Swagger3Config

作用:

  • 自动生成接口文档

  • 扫描 Controller

  • 定义接口分组、安全参数等

设计思想:

API 文档属于工程基础能力,不属于业务逻辑。

Druid 数据源配置

DruidConfig

DruidWallConfigRegister

DruidWallConfigRegister

单体 / 微服务条件配置

context.getEnvironment().getProperty(CommonConstant.CLOUD_SERVER_KEY)

如果存在云服务配置,就认为是微服务环境。

设计思想:

同一套公共代码,根据环境决定是否启用 Cloud 相关 Bean。

所以这里不是 Maven 依赖自动切换,而是:

启动模块决定依赖

配置条件决定 Bean 是否加载

org.jeecg.modules.base

这里通常放基础公共服务,例如:

BaseCommonMapper

BaseCommonService

它的作用是为公共层提供一些基础服务能力。

比如异常处理器里就依赖了:

@RestControllerAdvice

@Slf4j

public class JeecgBootExceptionHandler {

@Resource

BaseCommonService baseCommonService;

常见用途:

  • 记录系统日志

  • 查询公共字典

  • 查询公共用户信息

  • 获取公共系统配置

设计思想:

公共层有些能力需要访问数据库,但又不能直接依赖具体业务实现,所以通过基础服务接口抽象出来。

设计尊则

单向依赖原则

业务模块 → base-core

base-core 不反向依赖业务模块

这样公共层才稳定。

如果公共层依赖业务层,就会变成循环依赖。

横切能力集中管理

这些能力都属于横切关注点:

它们不属于某一个业务模块,所以放在 base-core 。

认证

鉴权

日志

异常

返回值

租户

数据权限

SQL 防护

接口文档

文件存储

统一契约

统一返回 Result

统一异常 JeecgBootException

统一登录用户 LoginUser

统一服务名 ServiceNameConstants

统一状态码 CommonConstant

好处:

  • 前后端约定稳定

  • 业务模块风格一致

  • 微服务之间调用格式统一

  • 排查问题更容易

配置优于硬编码

例如:

  • OSS 配置

  • MinIO 配置

  • Swagger 配置

  • Shiro 白名单

  • Cloud 条件

  • Druid 配置

这些都不应该写死在业务代码里。

应该通过:

application.yml

配置类

条件注解

配置属性类

可插拔能力

比如文件存储:

```

本地存储

MinIO

阿里云 OSS

七牛云

```

它们本质上都是"文件能力",不应该让业务模块关心底层是哪个供应商。

业务模块只应该调用统一工具或服务。

这就是可插拔思想。

单体和微服务兼容

单体模式

微服务模式

条件加载

配置判断

local-api / cloud-api 分离

starter 分离

jeecg-boot-module

JeecgBoot 的"业务扩展模块层"。

它不是系统核心层,也不是公共基础层,而是用来承载 可插拔业务模块、示例模块、AI 扩展模块 的地方。

启动层

业务扩展层:jeecg-boot-module

系统能力层:jeecg-module-system

公共基础层:jeecg-boot-base-core

jeecg-boot-module 更偏向:

具体业务能力

示例业务

扩展功能

AI / RAG 等独立业务模块

目前主要包括:

jeecg-boot-module

├── jeecg-module-demo

└── jeecg-boot-module-airag

设计思路

jeecg-boot-module 的核心设计思路是:

把非系统核心业务从 system 模块中拆出来,避免系统模块越来越臃肿。

也就是说:

  • 用户、角色、菜单、权限、部门等基础平台能力放在 jeecg-module-system

  • 通用框架能力放在 jeecg-boot-base-core

  • 独立业务、扩展业务、示例业务放在 jeecg-boot-module

这样项目不会变成一个大杂烩。

jeecg-boot-module 里的业务不应该反向修改公共核心能力。

jeecg-boot-module

jeecg-module-system / system-api

jeecg-boot-base-core

公共核心层不能依赖扩展业务层。

jeecg-boot-base-core

jeecg-boot-module

每个扩展模块应该有自己的:

controller

service

mapper

entity

vo/dto

resources

一个业务能力尽量在一个模块内闭合。

jeecg-boot-module 的存在,本质上让项目具备一种插件化思路:

需要 demo 模块 → 引入 jeecg-module-demo

需要 AI RAG → 引入 jeecg-boot-module-airag

需要新业务 → 新增一个独立 module

好处是:

  • 业务可拆分

  • 功能可选装

  • 模块可独立维护

  • 不影响系统核心能力'

jeecg-module-system

它是整个项目的 核心业务基座 ,可以理解为:

平台级业务能力模块,提供系统管理、用户/权限/菜单/字典/租户等基础平台能力。

启动层:system-start / system-cloud-start

核心业务层:jeecg-module-system ← 你现在问的

公共基础层:jeecg-boot-base-core
jeecg-module-system

├── jeecg-system-api ← 对外接口层

├── jeecg-system-biz ← 业务实现层

└── jeecg-system-start ← 单体启动层

jeecg-system-api

jeecg-system-api

├── jeecg-system-local-api

└── jeecg-system-cloud-api

设计思想:

业务能力的接口契约与调用方式分离。

  • local-api 给单体本 JVM 调用

  • cloud-api 给微服务场景下远程调用

这样 biz 实现层只写一份业务代码,上层调用方式可以切换。

jeecg-system-biz

这是真正承载业务逻辑的地方,一般会有:

modules

├── system ← 用户、角色、菜单、部门、字典、租户、权限...

├── message ← 消息、通知

├── monitor ← 日志、监控

├── online ← 在线表单、低代码配置

└── desform ← 设计器表单

设计思想:

业务能力放在 biz,启动层和 API 层只负责装配和暴露。

jeecg-system-start

路径: jeecg-system-start

单体 Spring Boot 启动入口,作用:

  • 聚合 biz、local-api、base-core

  • 提供单体 application.yml 配置

  • 作为本地开发与单体部署的启动入口

对应的微服务启动入口在 jeecg-server-cloud 下。

设计准则

3.1 接口与实现分离

业务接口放 jeecg-system-api ,实现放 jeecg-system-biz 。

好处:

  • 调用方只依赖接口,不直接耦合实现

  • 单体/微服务两种调用方式可以各自实现同一份接口契约

  • 后续重构业务实现更安全
    jeecg-module-system 负责平台能力, jeecg-boot-module 负责扩展业务。

不建议把业务功能塞进 system 模块里。

原因:

平台能力一旦被业务污染,升级与维护会越来越难。
biz 模块依赖:

  • base-core(基础设施、通用返回、异常、工具、配置)

  • 必要的数据库访问(MyBatis-Plus、Druid、多租户)

不反向依赖:

  • 启动模块

  • 外部扩展业务模块

  • 微服务治理模块(cloud/gateway/nacos 相关)

原则:

业务实现越纯,后面越容易复用。

jeecg-system-start 不应该写业务,它只负责:

引入依赖

写启动类

写 application.yml

提供数据库脚本与 Flyway(如果有)

提供前端可访问的静态资源
biz 模块里的业务代码不应该重新实现:

  • 登录用户获取

  • 权限判断

  • 统一返回 Result

  • 异常抛出

  • 字典翻译

  • 文件上传

  • 数据权限条件

这些都应该从 jeecg-boot-base-core 拿。

原则:

横切关注点不在业务层重复造轮子。

相关推荐
@insist1232 小时前
系统架构设计师-操作系统进程管理核心知识点详解
架构·系统架构·软考·系统架构设计师·软件水平考试
●VON2 小时前
AtomGit Flutter鸿蒙客户端:用户资料
flutter·华为·架构·跨平台·harmonyos·鸿蒙
SL-staff2 小时前
Web 白板技术架构深度解析:从渲染到协作的选型哲学
前端·架构
前端冒菜师3 小时前
别急着做 Agent,AI 工程化的第一步是 Skill 化
架构·ai编程
Patrick_Wilson3 小时前
为省一次回归测试,该不该把多个改动堆进一条分支?
git·ci/cd·架构
oqX0Cazj24 小时前
2026超火Go-Zero实战:从架构原理到高并发接口落地,彻底解决接口超时、雪崩问题
开发语言·架构·golang
蝎子莱莱爱打怪4 小时前
XZLL-IM干货系列 02|Protobuf 协议设计:从 JSON 切到二进制,每条消息省了 60%
后端·面试·架构