# springboot-learning **Repository Path**: learning_project/springboot-learning ## Basic Information - **Project Name**: springboot-learning - **Description**: Spring Boot 2.7.18 + JDK 8,覆盖 50 期学习路线全部可编码主题。 - **Primary Language**: Java - **License**: GPL-2.0 - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-07-18 - **Last Updated**: 2026-07-18 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Spring Boot 2 学习项目 > Spring Boot 2.7.18 + JDK 8,覆盖 50 期学习路线全部可编码主题。 --- ## 项目速览 | 项目 | 版本 | |------|------| | Spring Boot | 2.7.18 | | Spring Cloud | 2021.0.9 | | Spring Cloud Alibaba | 2021.0.5.0 | | Java | JDK 8 | | 构建工具 | Maven | | 数据库 | H2 (dev) / MySQL (test/prod) | --- ## 启动方式 ```bash # 1. 默认启动(dev profile + H2 内存数据库) mvn spring-boot:run # 2. 指定 profile 组合启动 mvn spring-boot:run -Dspring-boot.run.profiles=dev,sharding # 分库分表 mvn spring-boot:run -Dspring-boot.run.profiles=dev,dynamic-ds # 读写分离 mvn spring-boot:run -Dspring-boot.run.profiles=dev,nacos # Nacos 配置中心 mvn spring-boot:run -Dspring-boot.run.profiles=dev,seata # 分布式事务 # 3. 打包运行 mvn clean package -DskipTests java -jar target/springboot-learning-1.0.0-SNAPSHOT.jar --spring.profiles.active=dev ``` ### Profile 组合速查 | Profile 组合 | 对应期数 | 说明 | |------|:--:|------| | `dev` | 1-34 | 单体基础功能(含 Redis/Mongo,禁用 MQ/ES) | | `dev,nacos` | 35 | 接入 Nacos 配置中心,支持 `@RefreshScope` 动态刷新 | | `dev,dynamic-ds` | 42 | 一主一从一日志库读写分离 | | `dev,sharding` | 43 | 2 库 × 2 表 = 4 物理节点分库分表 | | `dev,seata` | 41 | Seata AT 模式分布式事务 | | `test` | — | MySQL + 全部中间件启用 | | `prod` | — | 生产环境配置 + Docker 部署 | --- ## 本地环境依赖 ### dev profile 默认中间件状态 | 中间件 | 状态 | 用途 | 版本要求 | |------|:--:|------|------| | **H2** | ✅ 内置 | 关系型数据库(内存模式) | 内嵌 | | **Redis** | ✅ 需要 | 缓存 / Session / 分布式锁 | 6.x+ | | **MongoDB** | 🔴 禁用 | NoSQL 文档存储 | 5.x+ | | **Elasticsearch** | 🔴 禁用 | 全文搜索 | 7.x | | **RabbitMQ** | 🔴 禁用 | 异步消息 | 3.9+ | | **Kafka** | 🔴 禁用 | 流式消息 | 3.x+ | | **Nacos** | ⚪ 可选 | 配置中心(需 `nacos` profile) | 2.x | | **Seata** | ⚪ 可选 | 分布式事务(需 `seata` profile) | 1.6.x | | **Xxl-Job** | ⚪ 可选 | 分布式定时任务 | 2.4.x | ``` 图例: ✅ = 内置/需要启动 🔴 = dev 自动禁用 ⚪ = 需手动启用对应 profile ``` > **快速开发**:只需要启动 Redis,其余中间件在 dev profile 下自动禁用。 > 如需完整测试 MongoDB/ES/RabbitMQ/Kafka,切换到 `test` profile 并启动对应中间件。 --- ## API 端点速查 ### 基础能力 | 模块 | 前缀 | 关键端点 | |------|------|------| | 用户管理 | `/api/users` | `GET /page` `POST /` `PUT /{id}` `DELETE /{id}` | | 认证授权 | `/api/auth` | `POST /login` `POST /register` `GET /info` | | 文件上传 | `/api/files` | `POST /upload` `GET /download/{filename}` | | Excel 导入导出 | `/api/excel/users` | `POST /import` `GET /export` | | 业务事务 | `/api/business` | `POST /place-order` `POST /seata-order` | ### 分布式与微服务 | 模块 | 前缀 | 关键端点 | |------|------|------| | 多数据源 | `/api/multi-ds` | `GET /from/master` `GET /from/slave` `POST /create` | | 分库分表 | `/api/sharding/orders` | `POST /create` `GET /page` `POST /hint-create` `GET /stats` | | Nacos 配置 | `/api/nacos/config` | `GET /current` `GET /detail` `GET /maintenance` `GET /guide` | | WebSocket | `/api/ws` | `POST /announcement` `GET /online-count` `POST /send/{userId}` | ### 监控 | 端点 | 说明 | |------|------| | `/actuator/health` | 健康检查 | | `/actuator/prometheus` | Prometheus 指标 | | `/actuator/nacosconfig` | Nacos 配置源信息(nacos profile) | | `/swagger-ui.html` | Swagger 接口文档 | | `/h2-console` | H2 数据库控制台(dev) | --- ## Nacos 配置中心(第 35 期) ### 前置准备 1. 下载并启动 Nacos: ```bash # Windows startup.cmd -m standalone # Linux / macOS sh startup.sh -m standalone ``` 2. 访问 Nacos 控制台:`http://localhost:8848/nacos`(默认账号密码均为 `nacos`) ### 创建配置 在 Nacos 控制台执行: ``` 配置管理 → 配置列表 → 新建配置 Data ID: springboot-learning-nacos.yaml Group: DEFAULT_GROUP 格式: YAML ``` 配置内容(YAML): ```yaml app: name: springboot2-learning-nacos version: 2.0.0 feature: newUserDiscount: false maxLoginAttempts: 3 upload: maxSize: 20MB system: maintenanceMode: false ``` ### 验证动态刷新 ```bash # 启动应用 mvn spring-boot:run -Dspring-boot.run.profiles=dev,nacos # 查看当前配置 curl http://localhost:8080/api/nacos/config/current # → "maintenanceMode": false # 在 Nacos 控制台修改: system.maintenanceMode: true → 发布 # 再次查看(无需重启!) curl http://localhost:8080/api/nacos/config/current # → "maintenanceMode": true ← 配置已实时生效 ``` ### Nacos 测试要点 | 测试场景 | 操作 | 预期结果 | |------|------|------| | 配置初始化 | 启动时 Nacos 无对应 Data ID | 走 `@Value` 默认值,应用正常启动 | | 配置动态刷新 | 修改配置项后发布 | `@RefreshScope` Bean 自动重建,值实时变更 | | 共享配置隔离 | 修改 `common-config.yaml` | 所有引用该配置的服务同步刷新 | | 配置优先级 | Nacos 配置 vs 本地 yml vs @Value 默认值 | Nacos 远程 > 本地 yml > 默认值 | | Nacos 不可用 | 启动时不连 Nacos | 应用正常启动,走本地配置和默认值兜底 | --- ## ShardingSphere 分库分表(第 43 期) ### 架构 ``` ShardingSphere-JDBC (逻辑层) ─ 逻辑表: t_order │ ├── 分库策略: database = user_id % 2 └── 分表策略: table = id % 2 │ ├─ ds0 (user_id % 2 == 0) │ ├── t_order_0 (id 偶数) │ └── t_order_1 (id 奇数) │ └─ ds1 (user_id % 2 == 1) ├── t_order_0 (id 偶数) └── t_order_1 (id 奇数) ``` ### 启动 ```bash mvn spring-boot:run -Dspring-boot.run.profiles=dev,sharding ``` > 无需外部数据库 —— 基于 H2 内存库模拟 2 个数据源,开箱即用。 ### 测试要点 | 测试场景 | 端点 | 预期行为 | |------|------|------| | 创建订单 | `POST /create` | 根据 user_id 路由到目标库,雪花 ID 生成 | | 批量创建 | `POST /batch` | 随机 user_id 分散到 4 个物理节点 | | 精确查询 | `GET /{id}` | 只访问 id%2 对应的唯一物理表 | | 按用户查询 | `GET /by-user/{userId}` | 单库跨 2 张表 UNION ALL | | 全量分页 | `GET /page` | 4 表归并排序后分页 | | Hint 强制路由 | `POST /hint-create` | 编程式指定 ds0 或 ds1 | | 统计信息 | `GET /stats` | 查看分片架构和表信息 | ### 验证 SQL 路由 启动后,控制台会打印每次 SQL 的实际路由(`sql-show: true`): ``` Actual SQL: ds0 ::: select * from t_order_0 where id = ? Actual SQL: ds0 ::: select * from t_order_1 where id = ? ``` --- ## Seata 分布式事务(第 41 期) ### 前置准备 1. 下载并启动 Seata Server: ```bash # 下载 seata-server-1.6.1.zip # 解压后启动 seata-server.bat -m file ``` 2. 启动应用: ```bash mvn spring-boot:run -Dspring-boot.run.profiles=dev,seata ``` ### 测试要点 | 测试场景 | 说明 | |------|------| | 正常提交 | 调用 `BusinessService` 下单,两个数据源均提交成功 | | 异常回滚 | 模拟第二个数据源异常,验证第一个数据源自动回滚 | | `@GlobalTransactional` | 事务边界由注解控制,跨服务间生效 | --- ## 动态多数据源 / 读写分离(第 42 期) ### 启动 ```bash mvn spring-boot:run -Dspring-boot.run.profiles=dev,dynamic-ds ``` ### 数据源分离架构 ``` @DS("master") → 主库(写操作) @DS("slave") → 从库(读操作) @DS("log") → 日志库(审计数据) ``` ### 测试要点 | 测试场景 | 端点 | 预期行为 | |------|------|------| | 从主库读 | `GET /api/multi-ds/from/master` | 数据来自主库 | | 从从库读 | `GET /api/multi-ds/from/slave` | 数据来自从库 | | 写入主库 | `POST /api/multi-ds/create` | 写入 `@DS("master")` 标注的方法 | | `@DS` 切换 | 观察日志 | 每个操作打印当前使用的数据源名称 | --- ## Docker 部署(第 32 期) ```bash # 构建镜像 docker build -t springboot-learning:1.0.0 . # 运行容器 docker run -d \ --name springboot-learning \ -p 8080:8080 \ -e JAVA_OPTS="-Xms256m -Xmx512m" \ springboot-learning:1.0.0 ``` > Dockerfile 使用**多阶段构建**(maven:3.8.6 → openjdk:8u342-jre-slim),JVM 参数已优化。 --- ## K6 性能测试(第 38 期) ### 安装 K6 ```bash # macOS brew install k6 # Windows (Chocolatey) choco install k6 # Linux sudo apt install k6 ``` ### 运行测试 ```bash # 先确保应用已启动 mvn spring-boot:run # 冒烟测试(验证功能正常) k6 run k6/k6-smoke-test.js # 负载测试(正常负载,持续 5 分钟) k6 run k6/k6-load-test.js # 压力测试(递增并发,找到系统瓶颈) k6 run k6/k6-stress-test.js # 自定义参数 k6 run --vus 50 --duration 60s k6/k6-load-test.js ``` | 脚本 | VUs | 时长 | 用途 | |------|:--:|------|------| | `k6-smoke-test.js` | 1 | 30s | 快速验证 | | `k6-load-test.js` | 20 | 5min | 日常负载 | | `k6-stress-test.js` | 50→200 | 阶梯递增 | 压力上限 | --- ## 代码覆盖率(JaCoCo) ```bash # 运行测试并生成覆盖率报告 mvn clean test # 查看报告 open target/site/jacoco/index.html ``` > JaCoCo 已集成在 pom.xml 中,测试完成后自动生成 HTML 报告。 --- ## 常见问题 ### 1. Redis 连接失败 ``` Caused by: io.lettuce.core.RedisConnectionException: Unable to connect to localhost:6379 ``` **解决**:启动本地 Redis 服务,或在 `application-dev.yml` 中注释 Redis 配置,添加排除: ```yaml spring.autoconfigure.exclude: - org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration ``` ### 2. MongoDB 连接失败 MongoDB 在 dev profile 下已默认排除自动配置。如需启用,注释掉 `application-dev.yml` 中的: ```yaml # 以下两行需同时注释才能启用 MongoDB # - org.springframework.boot.autoconfigure.data.mongo.MongoAutoConfiguration # - org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration ``` 然后启动本地 MongoDB 服务即可。 ### 3. Nacos 连接超时 ``` com.alibaba.nacos.api.exception.NacosException: Client not connected ``` **解决**: - 确认 Nacos Server 已启动并监听 8848 端口 - 确认 `bootstrap.yml` 中 `server-addr` 配置正确 - 不连 Nacos 时**不需要 `nacos` profile**,应用仍可正常启动 ### 4. ShardingSphere + Flyway 冲突 **表现**:Flyway 在 ShardingSphere 数据源上执行迁移失败。 **解决**:ShardingSphere 分片表由 `ShardingTableInitializer` 在启动时自动创建,Flyway 仅管理非分片的普通表。不要对分片表使用 Flyway 迁移脚本。 ### 5. @Value 注入为 null **常见原因**: - 类未被 Spring 管理(缺少 `@Component` / `@Configuration`) - 手动 `new` 创建对象 - 静态字段使用 `@Value`(不支持) **排查**:检查类是否有 Spring 注解,是否通过容器获取实例。 ### 6. ShardingSphere + Dynamic-Datasource 冲突 两者都会代理 `DataSource`,**不要同时激活** `sharding` 和 `dynamic-ds` profile。 ### 7. Seata 客户端注册失败 Seata Server 未启动时,可配置 `seata.enabled=false` 禁用,或使用 `file` 模式(不依赖注册中心)。 ### 8. JWT 密钥配置 JWT 签名密钥支持通过配置文件注入,适配不同环境: ```yaml # application.yml 或 application-dev.yml jwt: secret: your-256-bit-secret-key-here ``` 未配置时使用默认值,仅限开发环境。生产环境**必须**配置独立密钥。 ### 9. 权限说明 - `admin` 开头的用户名(如 `admin`, `admin_ops`)自动获得 `ROLE_ADMIN` 权限 - 其他用户仅拥有 `ROLE_USER` 权限 - ADMIN 角色可访问 Excel 导出、用户批量删除等管理端点 ### 10. 敏感数据脱敏架构 脱敏逻辑统一维护在 `SensitiveDataMasker.mask()`,避免多份代码重复: - **AOP 切面方式**:`SensitiveDataAspect` 对 `@SensitiveData` 注解方法返回值进行反射脱敏(适用下载、日志等非 JSON 场景) - **Jackson 序列化方式**:`serializer/SensitiveSerializer` 在 JSON 序列化阶段自动脱敏(适用 API 响应场景) - 两者共享 `SensitiveDataMasker` 的脱敏算法,支持 6 种类型(手机/身份证/姓名/邮箱/银行卡/地址) ### 11. 分层架构规范 - **Controller** → 仅依赖 **Service** 接口,不直接依赖 Mapper - **Service** → 调用 **Mapper**,处理业务逻辑和事务 - 构造器注入优先(`@RequiredArgsConstructor`),字段注入已全部消除 ### 12. 枚举与常量规范 - 订单状态(待支付/已支付/已取消等)统一使用 `OrderStatus` 枚举,禁止散布魔法数字 0/1/2 - 用户状态(启用/禁用)统一使用 `UserStatus` 枚举 - 响应状态码统一使用 `ResultCode` 枚举,禁止直接写 `401`、`200` 等数字 - 线程池参数已外部化到 `application.yml` 中的 `springboot.thread-pool` 命名空间,支持不同环境独立配置 - MyBatis-Plus 分页最大限制可通过 `mybatis-plus.page.max-limit` 配置项调整(默认 500) ### 13. DTO 校验与生产配置规范 - 所有 DTO 字段均有对应的 JSR-303 校验注解(`@NotBlank`、`@Min`、`@Max`、`@DecimalMin` 等) - 分页查询 DTO 的 `pageNum` / `pageSize` 统一添加 `@Min(1)` / `@Max(100)` 范围校验 - 订单单价添加 `@DecimalMin("0.01")` + `@Digits` 防止非法的负数/零价/精度溢出 - 可选字段(phone/email)使用 `^(...)?$` 正则允许空串通过校验 - 生产环境敏感配置(MySQL 密码、RabbitMQ 密码)无默认值,启动缺失时主动报错 - 禁止 `System.out/err.println`,统一使用 SLF4J 日志框架 ### 14. DRY 与转换器规范 - `UserServiceImpl` 中"用户不存在"校验提取为 `getUserOrThrow()` 方法,消除 3 处重复 - `OrderServiceImpl` 中"订单不存在"校验提取为 `getOrderOrThrow()` 方法,消除 2 处重复 - `ExcelController` 中 UserExcelDTO → User 手动逐字段 set 改为使用 `UserConverter` 的 MapStruct 映射 - `ShardingOrderController` 添加 `@Validated` + `@Min`/`@Max` 参数校验,防止非法分页参数 - JWT 签名密钥配置外部化到 `application.yml` 的 `jwt.secret` 下,支持环境变量覆盖 --- ## 项目结构 ``` src/main/java/com/example/springboot2/ ├── common/ # 公共类(Result、异常、拦截器) ├── config/ # 18 个配置类 ├── controller/ # 8 个 REST 控制器 ├── entity/ # 实体类 ├── enums/ # 状态枚举(UserStatus、OrderStatus) ├── mapper/ # MyBatis Mapper ├── mq/ # RabbitMQ / Kafka 生产者消费者 ├── service/ # 业务接口 │ └── impl/ # 业务实现 ├── aop/ # AOP 切面(请求日志、敏感数据脱敏切面) ├── util/ # 工具类 ├── websocket/ # WebSocket 端点 ├── webflux/ # WebFlux 响应式路由 ├── event/ # Spring Events 事件监听 ├── dto/ # 数据传输对象(请求) ├── vo/ # 视图对象(响应) ├── converter/ # MapStruct 对象转换器 ├── annotation/ # 自定义注解 ├── security/ # JWT 过滤器与工具 ├── document/ # Elasticsearch 文档实体 ├── repository/ # Mongo/ES Repository ├── job/ # XXL-JOB 定时任务 ├── cache/ # 缓存服务 ├── async/ # 异步任务 ├── serializer/ # Jackson 序列化脱敏器(复用 SensitiveDataMasker 算法) └── starter/ # 自定义 Starter(HttpLog) src/main/resources/ ├── application.yml # 主配置 ├── bootstrap.yml # Nacos 引导配置 ├── application-dev.yml # 开发环境 ├── application-test.yml # 测试环境 ├── application-prod.yml # 生产环境 ├── application-nacos.yml # Nacos 配置中心 ├── application-seata.yml # Seata 分布式事务 ├── application-dynamic-ds.yml # 多数据源读写分离 ├── application-sharding.yml # ShardingSphere 分库分表 ├── db/migration/ # Flyway 数据库迁移脚本 ├── mapper/ # MyBatis XML └── i18n/ # 国际化资源 k6/ # 性能测试脚本 Dockerfile # Docker 多阶段构建 .gitignore # 版本控制排除规则 ``` --- ## 学习路线覆盖 | 阶段 | 期数范围 | 主题 | 覆盖率 | |------|:---:|------|:---:| | 第一阶段:基础入门 | 1-6 | 概念、建项目、自动配置、多环境、日志、RESTful CRUD | ✅ 100% | | 第二阶段:核心能力 | 7-16 | MyBatis-Plus、Flyway、校验、事务、单测、Swagger、Jackson、拦截器、AOP、RestTemplate | ✅ 100% | | 第三阶段:进阶能力 | 17-26 | MapStruct、文件上传、EasyExcel、定时任务、XXL-JOB、Sa-Token、Security+JWT、Redis、异步、消息队列 | ✅ 100% | | 第四阶段:深入提升 | 27-34 | Events、WebSocket、i18n、数据脱敏、Docker、MongoDB、ES、WebFlux | ✅ 100% | | 第五阶段:微服务与分布式 | 35-44 | **Nacos 配置中心**、自定义 Starter、源码/调优、Feign、Sentinel+Gateway、Seata、多数据源、**ShardingSphere**、可观测性 | ✅ 100% | | 第六阶段:工程化落地 | 45-51 | 避坑、兼容性、工具类、CI/CD、职业发展、FAQ | 文档类 |