# ThinkBootCloud **Repository Path**: hongxinge/think-boot-cloud ## Basic Information - **Project Name**: ThinkBootCloud - **Description**: ThinkBootCloud 是一款基于 Spring Cloud Alibaba + Spring Boot 3 的轻量级微服务开发框架,专为 API/客户端服务场景设计。 - **Primary Language**: Java - **License**: MIT - **Default Branch**: main - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2026-05-09 - **Last Updated**: 2026-05-19 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # ThinkBootCloud > 🚀 轻量级微服务开发框架,专为C端客户端场景设计 **技术栈**: Spring Boot 3.2.5 | Spring Cloud 2023.0.1 | Spring Cloud Alibaba 2023.0.1.0 | Java 17 | RabbitMQ | RocketMQ **开源协议**: [MIT](LICENSE) | 完全免费 | 可自由商用 --- ## 📖 项目简介 ThinkBootCloud 是一款基于 Spring Cloud Alibaba + Spring Boot 3 的轻量级微服务开发框架。 与若依等后台管理系统不同,本框架**专注于C端客户端场景**(移动端App、Web前端、小程序等),去除了复杂的角色权限体系,仅保留基础的 Token 验证,让开发者能够**开箱即用,快速开发业务逻辑**。 ### 设计理念 - **开箱即用**:引入依赖,简单配置即可开始开发 - **轻量灵活**:模块化设计,按需引入,不臃肿 - **约定优于配置**:提供合理默认值,减少配置工作量 - **开发者友好**:统一响应格式、全局异常处理、自动装配 - **安全优先**:默认所有接口需要认证,明确标记才放行 --- ## 🏗️ 技术栈 | 组件 | 版本 | 说明 | |------|------|------| | Spring Boot | 3.2.5 | 核心框架 | | Spring Cloud | 2023.0.1 | 微服务框架 | | Spring Cloud Alibaba | 2023.0.1.0 | 阿里微服务组件 | | Nacos | 2.x | 注册中心 + 配置中心 | | MyBatis-Plus | 3.5.6 | ORM框架 | | Redis (Redisson) | 3.27.2 | 缓存 + 分布式锁 | | RabbitMQ | 3.12.x | 消息队列 | | RocketMQ | 5.3.x | 消息队列 | | JWT (JJWT) | 0.12.5 | Token认证 | | OpenFeign | 4.1.x | 服务间通信 | | Sentinel | 2023.0.1.0 | 限流熔断 | | Gateway | 4.1.x | API网关 | | Druid | 1.2.21 | 数据库连接池 | | Knife4j | 4.4.0 | API文档 | --- ## 📦 模块结构 ``` think-boot-cloud/ ├── pom.xml # 父POM(统一版本管理) ├── LICENSE # MIT 开源协议 ├── README.md # 使用文档 ├── templates/ # 部署模板目录 ├── think-boot-common/ # 公共模块 ├── think-boot-core/ # 核心模块(Web配置) ├── think-boot-auth/ # JWT认证模块 ├── think-boot-feign/ # OpenFeign集成模块 ├── think-boot-sentinel/ # Sentinel限流熔断模块 ├── think-boot-file/ # 文件上传模块 ├── think-boot-codegen/ # 代码生成器模块 ├── think-boot-mq-rabbitmq/ # RabbitMQ消息队列模块 ├── think-boot-mq-rocketmq/ # RocketMQ消息队列模块 ├── think-boot-gateway/ # API网关模块 ├── think-boot-nacos/ # Nacos注册配置模块 ├── think-boot-mybatis/ # MyBatis-Plus集成模块 ├── think-boot-redis/ # Redis缓存模块 └── think-boot-example/ # 示例模块(演示用法) ``` ### 模块说明 | 模块 | 说明 | 核心功能 | |------|------|----------| | **think-boot-common** | 公共基础模块 | 统一响应R、分页支持、业务异常、全局异常处理 | | **think-boot-core** | 核心配置模块 | CORS配置、Jackson时间序列化、请求日志 | | **think-boot-auth** | 认证模块 | JWT Token生成/验证、@IgnoreAuth注解、拦截器、UserContext | | **think-boot-feign** | 服务通信模块 | OpenFeign集成、Token自动传递、全局日志 | | **think-boot-sentinel** | 限流熔断模块 | Sentinel集成、自定义限流响应、Nacos规则源 | | **think-boot-gateway** | API网关模块 | 网关路由、Token验证、CORS、全局错误处理 | | **think-boot-nacos** | 服务注册模块 | Nacos服务发现、动态配置 | | **think-boot-mybatis** | 数据库模块 | MyBatis-Plus、BaseEntity、分页、自动填充 | | **think-boot-redis** | 缓存模块 | RedisTemplate封装、Redisson分布式锁 | | **think-boot-file** | 文件上传模块 | 本地存储、阿里云OSS、文件上传下载 | | **think-boot-codegen** | 代码生成器模块 | 基于数据库表自动生成CRUD代码 | | **think-boot-mq-rabbitmq** | 消息队列模块 | RabbitMQ集成、消息发送消费、延迟消息 | | **think-boot-mq-rocketmq** | 消息队列模块 | RocketMQ集成、普通/顺序/延迟/事务消息 | | **think-boot-example** | 示例模块 | 完整演示框架用法 | --- ## 🚀 快速开始 ### 环境要求 - JDK 17+ - Maven 3.6+ - MySQL 8.0+ - Redis 6.0+ - Nacos 2.x(可选,微服务场景需要) - RabbitMQ 3.12.x(可选,使用 RabbitMQ 消息队列时需要) - RocketMQ 5.3.4 LTS(可选,使用 RocketMQ 消息队列时推荐此稳定版本) ### 第一步:编译安装框架 ```bash # 克隆项目(任选一个仓库) # GitHub: git clone https://github.com/hongxinge/ThinkBootCloud.git # Gitee(国内镜像): git clone https://gitee.com/hongxinge/think-boot-cloud.git cd think-boot-cloud # 编译并安装到本地Maven仓库 mvn clean install -DskipTests ``` ### 第二步:创建你的业务项目 在你的项目中引入框架作为父POM: ```xml com.thinkboot think-boot-cloud 1.0.0 ``` 引入需要的模块依赖: ```xml com.thinkboot think-boot-common com.thinkboot think-boot-core com.thinkboot think-boot-auth com.thinkboot think-boot-mybatis com.thinkboot think-boot-redis com.thinkboot think-boot-feign com.thinkboot think-boot-sentinel com.thinkboot think-boot-file com.thinkboot think-boot-mq-rabbitmq com.thinkboot think-boot-mq-rocketmq ``` ### 第三步:配置 application.yml 在 `src/main/resources/application.yml` 中添加配置: ```yaml server: port: 8080 spring: application: name: your-service-name # 数据库配置(如果使用数据库) datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/your_db?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: your_password # Redis配置(如果使用缓存) data: redis: host: localhost port: 6379 password: database: 0 ``` ### 第四步:配置 application.yml(续) #### Sentinel 限流配置(可选) ```yaml spring: cloud: alibaba: sentinel: transport: dashboard: localhost:8080 # Sentinel 控制台地址 eager: true # 应用启动时立即初始化 ``` > **说明**:以上 Redis 和 Sentinel 配置均使用 Spring Cloud Alibaba 原生配置标准,开发者无需学习新的配置方式。 #### 框架增强配置(原生没有的便捷功能) ```yaml thinkboot: auth: jwt: # Base64编码的密钥(至少32位) # 可用在线工具生成:https://www.base64encode.org/ secret: dGhpbmstYm9vdC1qd3Qtc2VjcmV0LWtleS1tdXN0LWJlLWF0LWxlYXN0LTI1Ni1iaXRzLWxvbmc= # Token有效期(默认2小时) expiration: 7200000 # 刷新Token有效期(默认7天) refresh-expiration: 604800000 # 不需要Token验证的路径(白名单) skip-paths: - /api/auth/login - /api/auth/register - /doc.html - /swagger-resources/** - /v3/api-docs/** ``` ### 第四步:编写业务代码 #### 4.1 创建启动类 ```java package com.yourcompany.yourproject; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class YourProjectApplication { public static void main(String[] args) { SpringApplication.run(YourProjectApplication.class, args); } } ``` #### 4.2 创建实体类 继承 `BaseEntity`,自动包含 `id`、`createTime`、`updateTime`、`deleted` 等字段: ```java package com.yourcompany.yourproject.model.entity; import com.baomidou.mybatisplus.annotation.TableName; import com.thinkboot.mybatis.base.BaseEntity; import lombok.Data; import lombok.EqualsAndHashCode; @Data @EqualsAndHashCode(callSuper = true) @TableName("sys_user") public class User extends BaseEntity { private String username; private String password; private String nickname; private String email; private String phone; private Integer status; } ``` #### 4.3 创建 Mapper 和 Service ```java // Mapper - 继承 BaseMapper,自动拥有 CRUD 方法 package com.yourcompany.yourproject.mapper; import com.thinkboot.mybatis.base.BaseMapper; import com.yourcompany.yourproject.model.entity.User; import org.apache.ibatis.annotations.Mapper; @Mapper public interface UserMapper extends BaseMapper { } ``` ```java // Service 接口 - 继承 BaseService package com.yourcompany.yourproject.service; import com.thinkboot.mybatis.base.BaseService; import com.yourcompany.yourproject.model.entity.User; public interface UserService extends BaseService { User getByUsername(String username); } ``` ```java // Service 实现 - 继承 BaseServiceImpl package com.yourcompany.yourproject.service.impl; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.thinkboot.mybatis.base.BaseServiceImpl; import com.yourcompany.yourproject.mapper.UserMapper; import com.yourcompany.yourproject.model.entity.User; import com.yourcompany.yourproject.service.UserService; import org.springframework.stereotype.Service; @Service public class UserServiceImpl extends BaseServiceImpl implements UserService { @Override public User getByUsername(String username) { return getOne(new LambdaQueryWrapper().eq(User::getUsername, username)); } } ``` #### 4.4 创建 Controller ```java package com.yourcompany.yourproject.controller; import com.thinkboot.auth.annotation.IgnoreAuth; import com.thinkboot.auth.context.UserContext; import com.thinkboot.common.result.R; import com.yourcompany.yourproject.model.entity.User; import com.yourcompany.yourproject.service.UserService; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/api/users") public class UserController { private final UserService userService; public UserController(UserService userService) { this.userService = userService; } // 默认需要登录(无需添加任何注解) @GetMapping("/{id}") public R getById(@PathVariable Long id) { User user = userService.getById(id); if (user == null) { return R.error(404, "用户不存在"); } return R.success(user); } // 不需要登录(使用 @IgnoreAuth 注解) @IgnoreAuth @GetMapping("/public/info") public R publicInfo() { return R.success("这是公开信息"); } // 获取当前登录用户(默认需要登录) @GetMapping("/me") public R getCurrentUser() { String userId = UserContext.getCurrentUserId(); return R.success("当前用户ID: " + userId); } } ``` ### 第五步:运行测试 框架采用严格的测试保障,每个模块都有完善的测试覆盖: ```bash # 运行全部测试 mvn clean test # 查看测试覆盖率报告 mvn jacoco:report ``` **测试覆盖情况**: | 模块 | 测试数 | 覆盖内容 | |------|--------|----------| | think-boot-common | 41 | 统一响应、分页、全局异常、业务异常 | | think-boot-core | 15 | 配置属性、XSS过滤、TraceId | | think-boot-auth | 46 | JWT配置、Token生成/验证、拦截器(5种模式)、参数解析器 | | think-boot-gateway | 8 | 网关配置、限流、JWT验证 | | **总计** | **110+** | **核心模块覆盖率 80%+** | > **重要**:每次提交代码前必须通过全部测试,确保框架质量。 ### 第六步:启动项目 ```bash # 编译打包 mvn clean package -DskipTests # 启动 java -jar target/your-project-1.0.0.jar ``` 启动成功后,访问以下地址: - API文档:http://localhost:8080/doc.html - 接口测试:使用 Postman 或 curl --- ## 📖 使用指南 ### 统一响应格式 所有接口自动返回统一格式,前端无需特殊处理: ```json { "code": 200, "message": "success", "data": { ... }, "timestamp": 1700000000000 } ``` 常用方法: ```java // 成功响应(带数据) return R.success(user); // 成功响应(无数据) return R.success(); // 错误响应(自定义状态码) return R.error(404, "资源不存在"); // 错误响应(默认500) return R.error("服务器异常"); ``` ### 分页查询 ```java @GetMapping("/list") public PageResponse list(@RequestParam(defaultValue = "1") int pageNo, @RequestParam(defaultValue = "10") int pageSize) { // 创建分页对象 Page page = PageUtils.toPage(pageNo, pageSize); // 执行分页查询 Page result = userService.page(page); // 返回分页结果 return PageUtils.toPageResponse(result); } ``` 前端请求:`GET /api/users/list?pageNo=1&pageSize=10` 返回结果: ```json { "code": 200, "message": "success", "data": { "records": [...], "total": 100, "pages": 10, "pageNo": 1, "pageSize": 10, "hasPrevious": false, "hasNext": true }, "timestamp": 1700000000000 } ``` ### Token 认证 框架**默认所有接口都需要 Token 验证**,只有以下两种情况会放行: #### 放行条件 **方式1:配置免认证路径(批量管理)** ```yaml thinkboot: auth: jwt: skip-paths: - /api/auth/login # 登录接口 - /api/auth/register # 注册接口 - /api/public/** # 所有公开接口 - /doc.html # API文档 - /swagger-resources/** ``` **方式2:使用 @IgnoreAuth 注解(单个接口)** ```java @IgnoreAuth @PostMapping("/login") public R login(@RequestBody LoginRequest request) { // 免认证接口 } ``` #### 前端携带 Token ``` GET /api/users/1 Authorization: Bearer eyJhbGciOiJIUzI1NiJ9... ``` > **说明**:默认使用 `Authorization: Bearer ` 格式,这是 OAuth 2.0 标准格式。 #### 自定义 Token Header(可选) 如果你的前端不使用标准 Authorization 头,可以自定义: ```yaml thinkboot: auth: jwt: # 自定义请求头名称(默认 Authorization) token-header: X-Token # 自定义前缀(默认 "Bearer "),如果头名直接传token则留空 token-prefix: "" ``` 前端请求示例(自定义后): ``` GET /api/users/1 X-Token: eyJhbGciOiJIUzI1NiJ9... ``` #### 获取当前登录用户 ```java // 方式1:使用 UserContext(推荐) @GetMapping("/me") public R getCurrentUser() { String userId = UserContext.getCurrentUserId(); User user = userService.getById(Long.valueOf(userId)); return R.success(user); } // 方式2:使用 @CurrentUserId 注解(更简洁) @GetMapping("/me") public R getCurrentUser(@CurrentUserId String userId) { User user = userService.getById(Long.valueOf(userId)); return R.success(user); } ``` ### 微服务认证架构 框架采用**网关验证 + 内部信任**的设计,符合 Spring Cloud Alibaba 微服务规范。 #### 认证流程 ``` 客户端请求 → 网关(验证Token + 注入X-User-Id) → 服务A(信任X-User-Id) →[Feign + X-Internal-Call]→ 服务B(信任内部调用) ✅ 唯一安全验证点 ✅ 直接使用 ✅ 跳过验证 ``` **认证判断(3种模式)**: 1. **网关模式** - 包含 `X-User-Id` 头(网关验证后注入),直接信任,无需再次验证Token 2. **内部调用** - 包含 `X-Internal-Call: true` 头(Feign自动添加),跳过Token验证 3. **单体模式** - 直接访问微服务(无X-User-Id),必须验证Token > **设计说明**:C端API场景下,微服务部署在内网,网关是唯一公网入口。网关验证Token后注入 `X-User-Id`,微服务直接信任即可,无需额外签名验证,保持架构简单高效。 ### 性能优化说明 框架在多个层面进行了性能优化: #### 1. JWT认证优化 - **网关验证 + 内部信任**:网关是唯一验证JWT的地方,微服务通过 `X-User-Id` 头直接获取用户信息,无需重复解析Token - **ThreadLocal清理**:`afterCompletion` 中自动清理,防止内存泄漏 #### 2. 数据库连接池优化 - **Druid连接池**:默认配置 `initial-size=5, max-active=20, max-wait=60000ms` - **连接池监控**:自动统计连接使用情况,便于排查慢查询 #### 3. Redis缓存优化 - **Redisson分布式锁**:基于Redisson的高性能分布式锁,支持可重入锁 - **声明式缓存**:Spring Cache + Redis,自动缓存热点数据 - **JSON序列化**:自动处理对象序列化,支持复杂类型 #### 4. 网关限流优化 - **IP限流**:网关层基于滑动窗口实现IP限流,防止恶意请求 - **令牌桶算法**:支持自定义限流策略,保护下游服务 #### 5. 链路追踪优化 - **TraceId自动注入**:每个请求自动生成唯一TraceId,便于日志追踪 - **MDC集成**:TraceId自动注入到日志上下文,无需手动传递 #### 6. 响应优化 - **统一响应格式**:所有接口自动返回统一格式,减少前端处理 - **全局异常处理**:自动捕获异常并转换为友好响应,生产环境隐藏异常详情 --- ### OpenFeign 服务间调用 #### 1. 定义 Feign 接口 ```java package com.yourcompany.orderservice.feign; import com.thinkboot.common.result.R; import org.springframework.cloud.openfeign.FeignClient; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PathVariable; @FeignClient(name = "user-service", path = "/api/users") public interface UserFeignClient { @GetMapping("/{id}") R getUserById(@PathVariable Long id); } ``` #### 2. 使用 Feign 接口 ```java @RestController @RequestMapping("/api/orders") public class OrderController { private final UserFeignClient userFeignClient; public OrderController(UserFeignClient userFeignClient) { this.userFeignClient = userFeignClient; } @GetMapping("/{id}") public R getOrder(@PathVariable Long id) { // Token 会自动传递到 user-service R userResult = userFeignClient.getUserById(1L); Order order = orderService.getById(id); return R.success(order); } } ``` > **注意**:Token 传递是自动的,无需手动设置 Header。当 A 服务调用 B 服务时,当前请求的 Token 会自动传递到 B 服务。 ### Sentinel 限流熔断 #### 1. 配置文件(使用原生配置) ```yaml spring: cloud: alibaba: sentinel: transport: dashboard: localhost:8080 # Sentinel 控制台地址 eager: true # 应用启动时立即初始化 # 框架增强:Nacos 数据源配置(可选,原生没有) thinkboot: sentinel: datasource: nacos: enabled: true server-addr: localhost:8848 namespace: dev group-id: SENTINEL_GROUP data-id: your-service-flow-rules rule-type: flow ``` #### 2. 使用限流注解 ```java @SentinelResource(value = "getUserById", blockHandler = "handleBlock") @GetMapping("/{id}") public R getById(@PathVariable Long id) { return R.success(userService.getById(id)); } // 限流后的降级方法 public R handleBlock(Long id, BlockException ex) { return R.error(429, "请求过于频繁,请稍后再试"); } ``` ### Redis 缓存使用 #### 配置说明 框架使用 **Spring Boot 原生 `spring.redis.*` 配置**,开发者无需学习新的配置方式: ```yaml spring: data: redis: host: localhost # Redis 地址(原生配置) port: 6379 # Redis 端口(原生配置) password: # Redis 密码(原生配置) database: 0 # Redis 数据库(原生配置) timeout: 10000ms # 连接超时(原生配置) ``` Redisson 高级配置(可选,原生没有的功能): ```yaml thinkboot: redis: redisson: mode: single # single/cluster/sentinel connection-pool-size: 64 # 连接池大小 connection-minimum-idle-size: 10 # 最小空闲连接 timeout: 3000 # 超时时间(毫秒) # 集群模式节点列表 cluster: node-addresses: - redis://192.168.1.100:6379 - redis://192.168.1.101:6379 ``` #### 基本操作 ```java // 设置缓存(30分钟过期) RedisUtils.set("user:1", userObject, 30, TimeUnit.MINUTES); // 获取缓存 User user = (User) RedisUtils.get("user:1"); // 删除缓存 RedisUtils.delete("user:1"); // 判断是否存在 boolean exists = RedisUtils.hasKey("user:1"); // 设置过期时间 RedisUtils.expire("user:1", 1, TimeUnit.HOURS); ``` #### 分布式锁 ```java // 方式1:手动加锁解锁 RLock lock = DistributedLock.tryLock("lock:order:create", 3, 10, TimeUnit.SECONDS); try { if (lock != null) { // 执行业务逻辑 } } finally { DistributedLock.unlock("lock:order:create"); } // 方式2:函数式API(推荐) String result = DistributedLock.executeWithLock( "lock:order:create", () -> { // 执行业务逻辑 return "success"; }, 3, // 等待时间(秒) 10, // 锁持有时间(秒) TimeUnit.SECONDS ); ``` ### RabbitMQ 消息队列 框架集成了 RabbitMQ 消息队列,**自动配置,开箱即用**。开发者只需关注业务逻辑(发送消息和消费消息),其他全部由框架自动处理。 #### 1. 引入依赖 在你的项目中添加 RabbitMQ 模块依赖: ```xml com.thinkboot think-boot-mq-rabbitmq ``` #### 2. 配置 application.yml ```yaml spring: rabbitmq: host: localhost # RabbitMQ 地址 port: 5672 # RabbitMQ 端口 username: guest # 用户名 password: guest # 密码 virtual-host: / # 虚拟主机 thinkboot: mq: rabbitmq: enable: true # 启用 RabbitMQ exchange: thinkboot.default.exchange # 默认交换机名称 queue-prefix: thinkboot. # 队列前缀(自动创建的队列会使用此前缀) ``` #### 3. 自动配置说明 **框架自动完成以下配置,开发者无需关心**: - ✅ 自动创建 DirectExchange(默认交换机) - ✅ 自动创建默认队列(带死信队列配置) - ✅ 自动创建队列绑定关系 - ✅ 自动配置 JSON 序列化器 - ✅ 自动配置 RabbitTemplate **开发者只需要做两件事**: 1. 注入 `RabbitMessageSender` 发送消息 2. 使用 `@RabbitListener` 消费消息 #### 4. 发送消息(生产者) 注入 `RabbitMessageSender` 即可发送消息,**消息对象会自动序列化为 JSON**: ```java import com.thinkboot.mq.rabbitmq.core.RabbitMessageSender; import org.springframework.stereotype.Service; @Service public class OrderService { @Autowired private RabbitMessageSender messageSender; // 发送普通消息 public void createOrder(Order order) { // 1. 创建订单(你的业务逻辑) saveOrder(order); // 2. 发送消息(框架自动序列化) messageSender.send("order.created", order); } // 发送延迟消息(30分钟后超时取消) public void sendTimeoutMessage(Order order) { messageSender.sendDelay( "order.timeout", order, 30 * 60 * 1000 // 30分钟,单位毫秒 ); } // 发送到自定义交换机 public void sendToCustom(String exchange, String routingKey, Object data) { messageSender.send(exchange, routingKey, data); } } ``` #### 5. 消费消息(消费者) 使用 Spring 原生 `@RabbitListener` 注解,**框架自动反序列化为 Java 对象**: ```java import lombok.extern.slf4j.Slf4j; import org.springframework.amqp.rabbit.annotation.RabbitListener; import org.springframework.stereotype.Component; @Slf4j @Component public class OrderMessageConsumer { // 消费订单创建消息 @RabbitListener(queues = "thinkboot.order.created") public void handleOrderCreated(Order order) { log.info("收到订单创建消息: {}", order); // 处理订单创建后的业务逻辑(如发送通知、更新库存等) } // 消费订单超时消息 @RabbitListener(queues = "thinkboot.order.timeout") public void handleOrderTimeout(Order order) { log.info("收到订单超时消息: {}", order); // 处理订单超时取消业务逻辑 } } ``` #### 6. 配置项说明 | 配置项 | 默认值 | 说明 | |--------|--------|------| | `thinkboot.mq.rabbitmq.enable` | false | 是否启用 RabbitMQ | | `thinkboot.mq.rabbitmq.exchange` | thinkboot.default.exchange | 默认交换机名称 | | `thinkboot.mq.rabbitmq.queue-prefix` | thinkboot. | 队列前缀 | #### 7. 完整使用流程 ``` 1. 引入依赖 → think-boot-mq-rabbitmq 2. 配置连接 → spring.rabbitmq.* 3. 启用功能 → thinkboot.mq.rabbitmq.enable: true 4. 发送消息 → @Autowired + messageSender.send() 5. 消费消息 → @RabbitListener + 处理方法 ``` **总结:开发者只需关注第 4 步和第 5 步的业务逻辑,其他全部自动配置!** ### RocketMQ 消息队列 框架集成了 RocketMQ 消息队列,**自动配置,开箱即用**。支持普通消息、顺序消息、延迟消息、事务消息等多种消息类型。 #### 1. 引入依赖 在你的项目中添加 RocketMQ 模块依赖: ```xml com.thinkboot think-boot-mq-rocketmq ``` #### 2. 配置 application.yml ```yaml # RocketMQ 连接配置(使用原生配置) rocketmq: name-server: 127.0.0.1:9876 # NameServer 地址 producer: group: your-producer-group # 生产者组名称 thinkboot: mq: rocketmq: enable: true # 启用 RocketMQ producer-group: your-producer-group # 生产者组名称 send-message-timeout: 3000 # 发送超时(毫秒) retry-times-when-send-failed: 2 # 同步发送失败重试次数 max-message-size: 4194304 # 最大消息大小(字节,默认4MB) # 延迟消息配置(框架增强) delay-message: enabled: true default-delay-level: 3 # 默认延迟级别(1-18,对应不同延迟时间) ``` #### 3. 自动配置说明 **框架自动完成以下配置,开发者无需关心**: - ✅ 自动配置 RocketMQTemplate - ✅ 自动配置生产者(Producer) - ✅ 自动配置 JSON 序列化器 - ✅ 自动注册消费者监听器 **开发者只需要做两件事**: 1. 注入 `RocketMessageSender` 发送消息 2. 使用 `@RocketMQMessageListener` 消费消息 #### 4. 发送消息(生产者) 注入 `RocketMessageSender` 即可发送消息,**消息对象会自动序列化为 JSON**: ```java import com.thinkboot.mq.rocketmq.core.RocketMessageSender; import org.springframework.stereotype.Service; @Service public class OrderService { private final RocketMessageSender sender; public OrderService(RocketMessageSender sender) { this.sender = sender; } // 发送普通消息 public void createOrder(Order order) { saveOrder(order); sender.send("order-topic", order); } // 发送带 Tag 的消息 public void sendWithTag(Order order) { sender.send("order-topic", order, "TagA"); } // 发送顺序消息(保证同一订单的消息顺序消费) public void sendOrderly(Order order) { sender.sendOrderly("order-topic", order, String.valueOf(order.getId())); } // 发送延迟消息(延迟级别 1-18,对应不同延迟时间) // 级别3 = 10秒,级别4 = 30秒,级别5 = 1分钟,... public void sendDelay(Order order) { sender.sendDelay("delay-topic", order, 3); // 10秒后消费 } // 发送异步消息 public void sendAsync(Order order) { sender.sendAsync("async-topic", order); } // 发送单向消息(不等待响应,适合日志收集等场景) public void sendOneway(String logData) { sender.sendOneway("log-topic", logData); } } ``` #### 5. 消费消息(消费者) 使用 RocketMQ 原生 `@RocketMQMessageListener` 注解,**框架自动反序列化为 Java 对象**: ```java import lombok.extern.slf4j.Slf4j; import org.apache.rocketmq.spring.annotation.RocketMQMessageListener; import org.apache.rocketmq.spring.core.RocketMQListener; import org.springframework.stereotype.Component; @Slf4j @Component @RocketMQMessageListener( topic = "order-topic", consumerGroup = "order-consumer-group" ) public class OrderMessageConsumer implements RocketMQListener { @Override public void onMessage(Order order) { log.info("收到订单消息: {}", order); } } ``` **消费带 Tag 的消息**: ```java @Slf4j @Component @RocketMQMessageListener( topic = "order-topic", consumerGroup = "order-consumer-group", selectorExpression = "TagA || TagB" // 只消费指定 Tag 的消息 ) public class OrderTagConsumer implements RocketMQListener { @Override public void onMessage(Order order) { log.info("收到指定 Tag 的订单消息: {}", order); } } ``` **消费顺序消息**: ```java @Slf4j @Component @RocketMQMessageListener( topic = "order-topic", consumerGroup = "order-orderly-consumer-group", consumeMode = ConsumeMode.ORDERLY // 顺序消费 ) public class OrderOrderlyConsumer implements RocketMQListener { @Override public void onMessage(Order order) { log.info("按顺序收到订单消息: {}", order); } } ``` #### 6. RocketMQ 延迟级别说明 RocketMQ 默认支持 18 个延迟级别(不支持自定义延迟时间): | 级别 | 延迟时间 | 级别 | 延迟时间 | |------|----------|------|----------| | 1 | 1秒 | 10 | 6分钟 | | 2 | 5秒 | 11 | 7分钟 | | 3 | 10秒 | 12 | 8分钟 | | 4 | 30秒 | 13 | 9分钟 | | 5 | 1分钟 | 14 | 10分钟 | | 6 | 2分钟 | 15 | 20分钟 | | 7 | 3分钟 | 16 | 30分钟 | | 8 | 4分钟 | 17 | 1小时 | | 9 | 5分钟 | 18 | 2小时 | #### 7. 配置项说明 | 配置项 | 默认值 | 说明 | |--------|--------|------| | `rocketmq.name-server` | 必填 | NameServer 地址 | | `rocketmq.producer.group` | 必填 | 生产者组名称 | | `thinkboot.mq.rocketmq.enable` | false | 是否启用 RocketMQ | | `thinkboot.mq.rocketmq.producer-group` | thinkboot_default_producer_group | 生产者组名称 | | `thinkboot.mq.rocketmq.send-message-timeout` | 3000 | 发送超时(毫秒) | | `thinkboot.mq.rocketmq.retry-times-when-send-failed` | 2 | 同步发送失败重试次数 | | `thinkboot.mq.rocketmq.max-message-size` | 4194304 | 最大消息大小(字节) | #### 8. 完整使用流程 ``` 1. 引入依赖 → think-boot-mq-rocketmq 2. 配置连接 → rocketmq.name-server、rocketmq.producer.group 3. 启用功能 → thinkboot.mq.rocketmq.enable: true 4. 发送消息 → @Autowired + sender.send() 5. 消费消息 → @RocketMQMessageListener + 实现 RocketMQListener ``` **总结:开发者只需关注第 4 步和第 5 步的业务逻辑,其他全部自动配置!** ### 幂等性机制 框架提供 `@Idempotent` 注解,基于 Redis + Token 机制自动防止接口重复提交。 #### 1. 引入依赖 在你的项目中添加公共模块依赖(已包含幂等性功能): ```xml com.thinkboot think-boot-common ``` #### 2. 前端获取 Token 前端在提交表单前,先调用接口获取幂等 Token: ```bash GET /api/idempotent/token ``` 响应示例: ```json { "code": 200, "message": "success", "data": "550e8400e29b41d4a716446655440000", "timestamp": 1700000000000 } ``` #### 3. 后端使用注解 在需要防重复提交的接口上添加 `@Idempotent` 注解,并在请求头中携带 Token: ```java import com.thinkboot.common.idempotent.Idempotent; @RestController @RequestMapping("/api/orders") public class OrderController { // 防止订单重复提交 @Idempotent(key = "create_order", expire = 5, message = "订单正在处理中,请勿重复提交") @PostMapping public R createOrder(@RequestBody OrderDTO dto) { Order order = orderService.createOrder(dto); return R.success(order); } } ``` 前端请求示例: ```bash POST /api/orders X-Idempotent-Token: 550e8400e29b41d4a716446655440000 Content-Type: application/json {"productId": 1, "quantity": 2} ``` #### 4. 注解参数说明 | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | key | String | "" | 业务键前缀,用于区分不同场景 | | expire | long | 5 | Token 过期时间(秒) | | message | String | "请勿重复提交" | 重复提交时的错误提示 | #### 5. 工作原理 1. 前端调用 `GET /api/idempotent/token` 获取 Token(框架自动在 Redis 中创建,默认 5 秒过期) 2. 前端携带 `X-Idempotent-Token` 请求头提交请求 3. 拦截器检查 Redis 中该 Token 是否存在: - 存在:删除 Token,放行请求 - 不存在:拦截请求,返回 "请勿重复提交" 4. 重复提交时 Token 已被删除,自动拦截 #### 6. 配置项 ```yaml thinkboot: core: idempotent-enabled: true # 是否启用幂等性机制(默认 true) ``` ### Feign Fallback 防级联失败 框架提供 Fallback 示例,当服务调用失败时自动降级,防止级联雪崩。 #### 1. 使用 FallbackFactory(推荐) ```java import com.thinkboot.feign.fallback.ExampleFeignFallbackFactory; @FeignClient( name = "user-service", path = "/api/users", fallbackFactory = UserFeignFallbackFactory.class ) public interface UserFeignClient { @GetMapping("/{id}") R getUserById(@PathVariable Long id); } @Component public class UserFeignFallbackFactory implements FallbackFactory { private static final Logger log = LoggerFactory.getLogger(UserFeignFallbackFactory.class); @Override public UserFeignClient create(Throwable cause) { return new UserFeignClient() { @Override public R getUserById(Long id) { log.error("getUserById fallback, id={}, error={}", id, cause.getMessage()); return R.error(503, "用户服务暂时不可用"); } }; } } ``` #### 2. 启用 Fallback 配置 在 `application.yml` 中启用 Fallback: ```yaml spring: cloud: openfeign: circuitbreaker: enabled: true ``` #### 3. TraceId 自动传递 框架已配置 Feign 请求拦截器,自动传递以下请求头: - `Authorization` - Token 认证 - `X-User-Id` - 用户 ID - `X-Trace-Id` - 链路追踪 ID ### 响应缓存 框架基于 Spring Cache + Redis 提供声明式缓存。 #### 1. 基本使用 ```java import org.springframework.cache.annotation.Cacheable; import org.springframework.cache.annotation.CachePut; import org.springframework.cache.annotation.CacheEvict; @Service public class ProductService { // 查询时缓存结果 @Cacheable(value = "product", key = "#id", unless = "#result == null") public Product getById(Long id) { return productMapper.selectById(id); } // 更新时刷新缓存 @CachePut(value = "product", key = "#product.id") public Product update(Product product) { productMapper.updateById(product); return product; } // 删除时清除缓存 @CacheEvict(value = "product", key = "#id") public void delete(Long id) { productMapper.deleteById(id); } // 批量清除缓存 @CacheEvict(value = "product", allEntries = true) public void clearCache() { // 清除 product 缓存下所有条目 } } ``` #### 2. 缓存注解说明 | 注解 | 作用 | 适用场景 | |------|------|----------| | @Cacheable | 先查缓存,没有则执行方法并缓存 | 查询接口 | | @CachePut | 执行方法并更新缓存 | 更新接口 | | @CacheEvict | 执行方法并清除缓存 | 删除接口 | #### 3. 完整示例 参考 `think-boot-redis` 模块中的 [CacheExampleService](file:///G:/ThinkBootCloud/think-boot-redis/src/main/java/com/thinkboot/redis/example/CacheExampleService.java) 文件。 --- ### 代码生成器 框架提供了独立的代码生成器模块 `think-boot-codegen`,可以基于数据库表自动生成 Entity、Mapper、Service、ServiceImpl、Controller 等 CRUD 代码。 #### 1. 引入依赖 在你的项目中添加代码生成器模块依赖: ```xml com.thinkboot think-boot-codegen ``` #### 2. 使用代码生成器 创建代码生成器类并运行: ```java package com.yourcompany.yourproject; import com.baomidou.mybatisplus.annotation.IdType; import com.thinkboot.codegen.ThinkBootCodeGenerator; public class CodeGenerator { public static void main(String[] args) { ThinkBootCodeGenerator generator = new ThinkBootCodeGenerator(); generator.url("jdbc:mysql://localhost:3306/your_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai") .username("root") .password("your_password") .tableName("tb_user", "tb_order") .moduleName("system") .author("YourName") .outputPath("D:/project/your-project/src/main/java") .parentPackage("com.yourcompany") .useBaseEntity(true) .useLogicDelete(true) .logicDeleteField("deleted") .idType(IdType.ASSIGN_ID) .ignoreTablePrefix("tb_") .generate(); } } ``` #### 3. 生成结果 运行后会自动生成以下文件: ``` src/main/java/com/yourcompany/system/ ├── domain/entity/ │ ├── User.java │ └── Order.java ├── mapper/ │ ├── UserMapper.java │ ├── OrderMapper.java │ └── xml/ │ ├── UserMapper.xml │ └── OrderMapper.xml ├── service/ │ ├── UserService.java │ └── OrderService.java ├── service/impl/ │ ├── UserServiceImpl.java │ └── OrderServiceImpl.java └── controller/ ├── UserController.java └── OrderController.java ``` #### 4. 常用配置项 | 配置项 | 说明 | 默认值 | |--------|------|--------| | url | 数据库连接URL | jdbc:mysql://localhost:3306/thinkboot | | username | 数据库用户名 | root | | password | 数据库密码 | root | | tableName | 要生成的表名(支持多个) | 必填 | | moduleName | 模块名称(如system、order) | 空 | | author | 作者名 | thinkboot | | outputPath | 代码输出路径 | 当前目录/src/main/java | | parentPackage | 父包名 | com.thinkboot | | useBaseEntity | 是否继承BaseEntity | true | | useLogicDelete | 是否启用逻辑删除 | true | | ignoreTablePrefix | 忽略的表前缀 | tb_ | | idType | 主键类型 | ASSIGN_ID | #### 5. 选择性生成 可以通过 `disable*` 方法控制生成哪些文件: ```java generator.tableName("tb_user") .disableController() .disableService() .disableServiceImpl() .generate(); ``` > **提示:** 生成代码后,请根据实际业务需求调整生成的代码,尤其是Controller中的接口逻辑。 --- ## 🔧 完整配置参考 ```yaml server: port: 8080 spring: application: name: your-service-name # 数据库 datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/your_db?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai username: root password: your_password druid: initial-size: 5 min-idle: 5 max-active: 20 max-wait: 60000 # Redis(使用原生配置) data: redis: host: localhost port: 6379 password: database: 0 timeout: 10000ms # 哨兵模式配置(如需使用哨兵) # sentinel: # master: mymaster # nodes: 192.168.1.100:26379,192.168.1.101:26379,192.168.1.102:26379 # Nacos(微服务场景) cloud: nacos: discovery: server-addr: localhost:8848 namespace: dev config: server-addr: localhost:8848 namespace: dev file-extension: yml # Sentinel(使用原生配置) alibaba: sentinel: transport: dashboard: localhost:8080 eager: true # MyBatis-Plus mybatis-plus: mapper-locations: classpath*:mapper/**/*.xml type-aliases-package: com.yourcompany.yourproject.model.entity configuration: map-underscore-to-camel-case: true cache-enabled: false global-config: db-config: id-type: ASSIGN_ID logic-delete-field: deleted logic-delete-value: 1 logic-not-delete-value: 0 # Knife4j API文档 knife4j: enable: true openapi: title: Your Project API description: API 文档 version: 1.0.0 # ThinkBoot 框架配置 thinkboot: # 核心配置 core: enable-cors: true cors-allowed-origins: ["*"] max-upload-size: 10 # JWT认证 auth: jwt: secret: dGhpbmstYm9vdC1qd3Qtc2VjcmV0LWtleS1tdXN0LWJlLWF0LWxlYXN0LTI1Ni1iaXRzLWxvbmc= expiration: 7200000 refresh-expiration: 604800000 skip-paths: - /api/auth/login - /api/auth/register - /doc.html - /swagger-resources/** - /v3/api-docs/** # Redis/Redisson(使用 spring.redis.* 原生配置) # Redis 基础配置(原生) redis: host: localhost port: 6379 password: database: 0 # Redisson 高级配置(框架增强,原生没有的) redisson: mode: single # single/cluster/sentinel # 集群模式节点列表(仅 cluster/sentinel 模式需要) # cluster: # node-addresses: # - redis://192.168.1.100:6379 # - redis://192.168.1.101:6379 # - redis://192.168.1.102:6379 # 连接池配置 connection-pool-size: 64 connection-minimum-idle-size: 10 timeout: 3000 # Sentinel(使用原生配置,仅需配置 Nacos 数据源增强) sentinel: datasource: nacos: enabled: false # server-addr: localhost:8848 # namespace: dev # group-id: SENTINEL_GROUP # data-id: your-service-flow-rules # rule-type: flow ``` --- ## 💾 数据源配置 框架默认使用**单数据源**配置(满足 90%+ 的项目需求)。如需使用多数据源(读写分离、分库),框架提供了完整的示例配置。 ### 单数据源(默认) 在 `application.yml` 中配置即可: ```yaml spring: datasource: type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/your_db username: root password: your_password ``` ### 多数据源(读写分离) 框架提供了现成的示例配置文件,位于: ``` think-boot-example/src/main/resources/datasource-examples/ ├── single-datasource-example.yml # 单数据源示例 ├── multi-datasource-example.yml # 读写分离示例 └── dynamic-datasource-example.yml # 分库示例 ``` **使用步骤:** 1. 在 `pom.xml` 中添加依赖: ```xml com.baomidou dynamic-datasource-spring-boot3-starter 4.3.0 ``` 2. 将 `multi-datasource-example.yml` 中的配置复制到 `application.yml` 3. 在代码中使用 `@DS` 注解切换数据源: ```java @Service public class UserServiceImpl extends BaseServiceImpl { // 默认使用主库(写操作) public void createUser(User user) { this.save(user); } // 使用从库(读操作) @DS("slave_1") public User getUserById(Long id) { return this.getById(id); } } ``` ### 分库配置(按业务分离) 参考 `dynamic-datasource-example.yml`,适用于用户库、订单库、日志库分离的场景: ```java @Service @DS("order_db") // 整个类使用订单库 public class OrderServiceImpl extends BaseServiceImpl { public Order createOrder(Order order) { this.save(order); // 使用 order_db return order; } } ``` > **注意事项:** > - 同一事务中只能使用一个数据源 > - 跨数据源无法使用本地事务,需要使用分布式事务(如 Seata) > - 建议避免跨库事务,使用消息队列等方式异步处理 --- ## 📋 部署模板 框架提供开箱即用的部署模板,位于 `templates/` 目录,开发者可按需复制到项目中使用。 ### Docker Compose 一键部署 ```bash cd templates/docker cp .env.example .env # 修改环境变量 docker-compose up -d ``` 包含服务:Nacos、MySQL、Redis、RabbitMQ、Gateway ### CI/CD 配置 - **GitHub Actions**: 复制 `templates/ci-cd/.github-workflows.yml` 到 `.github/workflows/` - **GitLab CI**: 复制 `templates/ci-cd/gitlab-ci.yml` 到项目根目录 ### Nginx 反向代理 复制 `templates/nginx/gateway.conf` 到 Nginx 配置目录,修改域名和 SSL 证书路径。 --- ## 📝 项目结构建议 ``` your-project/ ├── src/main/java/com/yourcompany/yourproject/ │ ├── YourProjectApplication.java # 启动类 │ ├── controller/ # 控制器 │ │ ├── UserController.java │ │ └── AuthController.java │ ├── service/ # 服务接口 │ │ ├── UserService.java │ │ └── impl/ # 服务实现 │ │ └── UserServiceImpl.java │ ├── mapper/ # 数据访问层 │ │ └── UserMapper.java │ ├── model/ │ │ ├── entity/ # 数据库实体 │ │ │ └── User.java │ │ └── dto/ # 数据传输对象 │ │ ├── LoginRequest.java │ │ └── UserDTO.java │ └── config/ # 项目特定配置 │ └── YourConfig.java └── src/main/resources/ ├── application.yml # 配置文件 └── mapper/ # XML Mapper(可选) └── UserMapper.xml ``` --- ## 🐛 常见问题 ### Q1: JWT密钥怎么生成? **方式1:在线生成** 访问 https://www.base64encode.org/ ,输入任意字符串(至少32位),点击编码。 **方式2:代码生成** ```java import cn.hutool.crypto.SecureUtil; import cn.hutool.codec.Base64; String key = SecureUtil.generateKey("HmacSHA256").toString(); String base64Key = Base64.encode(key.getBytes()); System.out.println(base64Key); ``` ### Q2: 如何关闭某个接口的Token验证? 有两种方式: **方式1**:在配置文件的 `skip-paths` 中添加路径: ```yaml thinkboot: auth: jwt: skip-paths: - /api/users/public/** ``` **方式2**:在方法或类上添加 `@IgnoreAuth` 注解: ```java @IgnoreAuth @GetMapping("/public/info") public R publicInfo() { return R.success("这是公开信息"); } ``` ### Q3: 如何自定义分页大小限制? 在请求中传递 `pageNo` 和 `pageSize` 参数,框架默认限制 pageSize 最大为 100: ```java // 修改 PageRequest 中的默认限制 public class CustomPageRequest extends PageRequest { @Override public int getPageSize() { return pageSize < 1 ? 10 : (pageSize > 500 ? 500 : pageSize); } } ``` ### Q4: Gateway网关如何配置路由? ```yaml spring: cloud: gateway: routes: - id: user-service uri: lb://user-service predicates: - Path=/api/users/** - id: order-service uri: lb://order-service predicates: - Path=/api/orders/** ``` ### Q5: 如何获取当前登录用户信息? ```java @GetMapping("/me") public R getCurrentUser() { String userId = UserContext.getCurrentUserId(); User user = userService.getById(Long.valueOf(userId)); return R.success(user); } ``` ### Q6: 微服务之间如何通信? 推荐使用 **OpenFeign**(已内置): 1. 定义 `@FeignClient` 接口 2. 注入接口直接调用 3. **Token自动传递**,无需手动处理 ### Q7: 如何自定义 Token 请求头? 默认使用 `Authorization: Bearer `,如需自定义: ```yaml thinkboot: auth: jwt: token-header: X-Token # 自定义头名称 token-prefix: "" # 留空表示不用前缀 ``` --- ## 📄 开源协议 本项目采用 [MIT License](LICENSE) 开源协议。 **MIT 协议是最宽松的开源协议之一,意味着:** - ✅ 完全免费使用 - ✅ 可自由修改源码 - ✅ 可自由分发 - ✅ 可自由商用 - ✅ 无需支付任何费用 - ✅ 无强制开源要求 **唯一要求:在软件副本中包含原始版权声明和许可声明即可。** --- ## 🤝 参与贡献 欢迎提交 Issue 和 Pull Request! 1. Fork 本仓库 2. 创建你的特性分支 (`git checkout -b feature/AmazingFeature`) 3. 提交你的改动 (`git commit -m 'Add some AmazingFeature'`) 4. 推送到分支 (`git push origin feature/AmazingFeature`) 5. 提交 Pull Request --- ## 📮 联系方式 - 项目地址: - GitHub: https://github.com/hongxinge/ThinkBootCloud - Gitee(国内镜像): https://gitee.com/hongxinge/think-boot-cloud - 问题反馈: - GitHub Issues: https://github.com/hongxinge/ThinkBootCloud/issues - Gitee Issues: https://gitee.com/hongxinge/think-boot-cloud/issues