# ThinkBoot
**Repository Path**: hongxinge/think-boot
## Basic Information
- **Project Name**: ThinkBoot
- **Description**: ThinkBoot 是一个基于 Spring Boot 3 的轻量级快速开发框架,专为 API/客户端服务场景设计。
- **Primary Language**: Java
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 2
- **Forks**: 2
- **Created**: 2026-05-09
- **Last Updated**: 2026-05-19
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
# ThinkBoot
轻量级 Spring Boot 3 快速开发框架
简介 •
特性 •
快速开始 •
模块说明 •
配置说明 •
使用示例 •
开源协议
---
## 简介
ThinkBoot 是一个基于 Spring Boot 3 的轻量级快速开发框架,专为 API/客户端服务场景设计。
与若依(RuoYi)等重量级框架不同,ThinkBoot **不包含复杂的角色权限体系**,只提供客户端最常用的 Token 认证功能。框架采用模块化设计,所有第三方依赖均可按需启用,无需复杂配置即可开箱即用。
**设计哲学**:让开发者更关注业务逻辑,减少繁琐的配置工作。
## 特性
- **轻量简洁**:无冗余功能,聚焦 API 服务核心需求
- **模块化设计**:各功能模块独立,按需引入
- **按需加载**:所有第三方依赖通过条件配置加载,不配置不报错
- **开箱即用**:零配置或最小配置即可启动
- **企业级特性**:内置 XSS 防护、接口幂等性、分布式锁、Spring Cache 支持
- **代码生成**:内置代码生成器,一键生成 CRUD 代码
- **多数据源**:内置动态数据源支持,轻松切换
- **统一存储**:MinIO/阿里云 OSS/腾讯云 COS 统一接口
- **免费开源**:遵循 MIT 开源协议,可自由商用
## 技术栈
| 组件 | 技术 | 版本 |
|------|------|------|
| 基础框架 | Spring Boot | 3.2.5 |
| Java 版本 | JDK | 17+ |
| 认证鉴权 | Sa-Token | 1.45.0 |
| ORM 框架 | MyBatis-Plus | 3.5.6 |
| 多数据源 | Dynamic Datasource | 4.3.0 |
| 缓存 | Spring Data Redis / Spring Cache | - |
| 连接池 | HikariCP | - |
| 工具库 | Hutool | 5.8.27 |
| API 文档 | SpringDoc (OpenAPI 3) | 2.5.0 |
| 对象存储 | MinIO / 阿里云 OSS / 腾讯云 COS | - |
## 快速开始
### 1. 环境要求
- JDK 17 或以上
- Maven 3.6+
- MySQL 8.0+(可选)
- Redis(可选)
### 2. 引入依赖
在你的 `pom.xml` 中引入 ThinkBoot 父 POM:
```xml
com.thinkboot
think-boot
1.0.0
```
引入需要的模块:
```xml
com.thinkboot
think-boot-web
com.thinkboot
think-boot-auth
com.thinkboot
think-boot-database
com.thinkboot
think-boot-redis
com.thinkboot
think-boot-cache
com.thinkboot
think-boot-security
com.thinkboot
think-boot-storage
```
### 3. 配置文件
创建 `application.yml`:
```yaml
server:
port: 8080
# 数据源配置(不使用时可不配置)
spring:
datasource:
dynamic:
primary: master
datasource:
master:
url: jdbc:mysql://localhost:3306/your_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
# Redis 配置(不使用时可不配置)
data:
redis:
host: localhost
port: 6379
password:
database: 0
# MyBatis-Plus 配置
mybatis-plus:
mapper-locations: classpath*:/mapper/**/*.xml
configuration:
map-underscore-to-camel-case: true
# ThinkBoot 模块开关
think-boot:
auth:
enabled: true # 启用认证模块
database:
enabled: true # 启用数据库模块
redis:
enabled: false # 启用 Redis 模块
storage:
type: minio # 对象存储类型:minio/aliyun/tencent
minio:
endpoint: http://localhost:9000
access-key: minioadmin
secret-key: minioadmin
bucket-name: default
cors:
enabled: true # 启用跨域
swagger:
enabled: true # 启用 API 文档
```
### 4. 初始化数据库
执行示例项目中的 SQL 初始化脚本:
```bash
mysql -u root -p < think-boot-example/src/main/resources/sql/init.sql
```
> **说明**:`init.sql` 会创建 `thinkboot` 数据库、`sys_user` 表和 `demo_article` 表,并插入测试数据(用户名:admin/user,密码:123456,使用 BCrypt 加密)。
### 5. 运行项目
```bash
# 编译
mvn clean install
# 运行示例项目
cd think-boot-example
mvn spring-boot:run
```
访问 API 文档:http://localhost:8080/swagger-ui.html
## 模块说明
### think-boot-core
核心模块,提供基础工具类和常量。
**包含内容**:
- 常量定义:`CommonConstants`、`RedisConstants`
- 枚举:`ResultCode`
- 异常:`BusinessException`
- 工具类:`ServletUtils`、`ExcelUtils`
- 对象转换:`BaseConverter`(MapStruct 接口)
**使用示例**:
```java
// DTO 转实体
@Mapper(componentModel = "spring")
public interface UserConverter extends BaseConverter {
}
// 使用
@Autowired
private UserConverter userConverter;
User user = userConverter.to(userDTO);
List users = userConverter.toList(userDTOList);
```
### think-boot-web
Web 层模块,提供统一响应、异常处理等。
**包含内容**:
- 统一响应:`R` 类
- 分页响应:`PageResult` 类
- 全局异常处理:`GlobalExceptionHandler`
- Sa-Token 异常处理:`SaTokenExceptionHandler`(自动将认证异常转为 401/403 响应)
- 日志配置:TraceId 追踪
- Swagger 配置:API 文档
> **注意**:框架已移除自定义 Jackson 和 CORS 配置类。请使用原生配置:
> - Jackson 日期格式:`spring.jackson.date-format`
> - CORS 跨域:`spring.web.cors.*`
**使用示例**:
```java
@RestController
public class UserController {
@GetMapping("/user/{id}")
public R getUser(@PathVariable Long id) {
User user = userService.getById(id);
return R.ok(user);
}
@PostMapping("/user")
public R createUser(@RequestBody User user) {
userService.save(user);
return R.ok();
}
}
```
### think-boot-auth
认证模块,基于 Sa-Token 1.45.0 实现。
**包含内容**:
- 认证配置:`SaTokenConfigure`(支持注解策略重写 + Redis 集成)
- 拦截器配置:`SaTokenWebMvcConfig`(原生 SaInterceptor + SaServletFilter)
- 认证异常处理:`SaTokenExceptionHandler`(自动将 NotLoginException 转为 401 响应)
- 认证服务:`AuthService`
- 登录用户:`LoginUser`
- 忽略认证注解:`@IgnoreAuth`(与 Sa-Token 原生 `@SaIgnore` 等效)
**框架配置设计原则**:
| 配置类型 | 来源 | 说明 |
|----------|------|------|
| 基础配置 | `sa-token.*` | Sa-Token 原生配置,开发者可直接参考官方文档 |
| 增强配置 | `think-boot.auth.exclude-paths` | 框架增强功能,方便开发者快速配置白名单 |
**Sa-Token 配置**:
ThinkBoot 完整支持 Sa-Token 的所有配置项,在 `application.yml` 中配置即可:
```yaml
# ==========================================
# Sa-Token 配置(文档:https://sa-token.cc)
# ==========================================
sa-token:
# token 名称(同时也是 cookie 名称,建议前端在 Header 中传递此字段)
token-name: Authorization
# token 有效期(单位:秒)默认30天,-1 代表永久有效
timeout: 2592000
# token 最低活跃频率(单位:秒),默认-1 代表不限制,永不冻结
active-timeout: -1
# 是否允许同一账号多地同时登录(为 true 时允许一起登录,为 false 时新登录挤掉旧登录)
is-concurrent: true
# 在多人登录同一账号时,是否共用一个 token(为 true 时所有登录共用一个 token,为 false 时每次登录新建一个 token)
is-share: false
# token 风格(uuid、simple-uuid、random-32、random-64、random-128、tik)
token-style: uuid
# 是否输出操作日志
is-log: false
```
**Sa-Token 集成 Redis**(可选):
Sa-Token 默认将数据保存在内存中(读写速度最快,避免了序列化/反序列化性能消耗),但存在以下限制:
- 重启后数据会丢失
- 无法在分布式环境中共享数据
集成 Redis 可解决上述问题,实现重启数据不丢失、分布式环境多节点会话一致。
**方式 1:Sa-Token 整合 RedisTemplate(官方推荐,省心省事)**
> 如果你只想“省心省事”,我们推荐直接使用此方案,而不必进行过多研究。
```xml
cn.dev33
sa-token-redis-template
${sa-token.version}
org.apache.commons
commons-pool2
```
**方式 2:Sa-Token 整合 Redis(使用 Jackson 序列化)**
```xml
cn.dev33
sa-token-redis-jackson
${sa-token.version}
org.apache.commons
commons-pool2
```
- 优点:Session 序列化后可读性强,可灵活手动修改
- 缺点:兼容性稍差
> ThinkBoot 框架默认提供 **方式 2**(Jackson 序列化)作为可选依赖,但如果你希望使用最省心的方案,建议改为引入 **方式 1**(RedisTemplate)。
**自定义序列化方案**(可选):
框架默认以 JSON 格式存储数据。如需更换序列化方案,可引入以下依赖:
```xml
cn.dev33
sa-token-fastjson2
${sa-token.version}
```
或自定义 String 序列化方案:
```java
// 设置序列化方案: jdk序列化 (base64编码)
@PostConstruct
public void rewriteComponent() {
SaManager.setSaSerializerTemplate(new SaSerializerTemplateForJdkUseBase64());
}
```
**集成 Redis 注意事项**:
1. **需要配置 Redis 连接信息**:只有项目初始化了正确的 Redis 实例,Sa-Token 才可以使用 Redis 进行数据持久化。
2. **框架自动保存数据**:集成 Redis 只需要引入对应的 pom 依赖即可,框架所有上层 API 保持不变,不需要手动保存。
3. **集成包版本问题**:Sa-Token-Redis 集成包的版本尽量与 Sa-Token-Starter 集成包的版本一致(ThinkBoot 已通过 `${sa-token.version}` 统一管理),否则可能出现兼容性问题。
**使用示例**:
```java
@RestController
public class AuthController {
@Autowired
private AuthService authService;
@PostMapping("/login")
public R login(@RequestParam String username, @RequestParam String password) {
// 1. 查询用户
User user = userService.lambdaQuery()
.eq(User::getUsername, username)
.one();
// 2. 验证密码(BCrypt)
if (user == null || !authService.checkPassword(password, user.getPassword())) {
return R.fail("用户名或密码错误");
}
// 3. 登录并返回 token
String token = authService.login(user.getId(), user.getUsername());
return R.ok(token);
}
@GetMapping("/user/info")
public R getUserInfo() {
return R.ok(authService.getLoginUser());
}
}
```
> **密码加密说明**:框架使用 BCrypt 算法加密密码(由 Hutool 提供),注册时使用 `authService.encryptPassword(rawPassword)` 加密,登录时使用 `authService.checkPassword(rawPassword, hashedPassword)` 验证。
**跳过认证的方式**:
方式一:使用 `@IgnoreAuth` 注解(推荐)
```java
@RestController
public class AuthController {
@IgnoreAuth
@PostMapping("/login")
public R login(@RequestParam String username, @RequestParam String password) {
// 不需要登录即可访问
return R.ok("token");
}
@IgnoreAuth
@PostMapping("/register")
public R register(@RequestBody User user) {
// 注册接口不需要登录
return R.ok();
}
}
```
方式二:使用 Sa-Token 原生 `@SaIgnore` 注解(与 `@IgnoreAuth` 等效)
```java
@RestController
public class AuthController {
@SaIgnore
@PostMapping("/login")
public R login(@RequestParam String username, @RequestParam String password) {
return R.ok("token");
}
}
```
方式三:在 Controller 类上标注(整个类跳过认证)
```java
@IgnoreAuth
@RestController
public class PublicController {
// 所有接口都不需要登录
}
```
方式四:在配置文件中配置白名单(框架增强功能)
```yaml
think-boot:
auth:
exclude-paths:
- /login
- /register
- /api/public/**
```
> **说明**:Sa-Token 原生未提供 YAML 白名单配置方式。ThinkBoot 封装了 `think-boot.auth.exclude-paths` 增强配置,方便开发者快速排除接口,无需编写代码。如需更复杂的路由鉴权规则,可直接使用 Sa-Token 原生的 `SaRouter`(见下方)。
> **说明**:ThinkBoot 的 `exclude-paths` 配置与 Sa-Token 原生的路由拦截配置**完全兼容**。ThinkBoot 在内部使用 `SaRouter.notMatch()` 实现白名单排除,你也可以直接使用 Sa-Token 原生的 `SaRouter` 进行更复杂的路由鉴权(见下方)。
**使用 Sa-Token 原生路由拦截**(高级用法):
如果你需要更复杂的路由鉴权规则(如按模块划分不同权限),可以创建自定义配置类覆盖 ThinkBoot 的默认拦截器:
```java
@Configuration
public class CustomSaTokenConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SaInterceptor(handler -> {
// 登录校验 -- 拦截所有路由,排除登录和公开接口
SaRouter.match("/**")
.notMatch("/login", "/register", "/api/public/**")
.check(r -> StpUtil.checkLogin());
// 权限校验 -- 不同模块校验不同权限
SaRouter.match("/admin/**", r -> StpUtil.checkPermission("admin"));
SaRouter.match("/user/**", r -> StpUtil.checkPermission("user"));
// 角色校验
SaRouter.match("/manager/**", r -> StpUtil.checkRoleOr("admin", "manager"));
})).addPathPatterns("/**");
}
}
```
> **提示**:自定义拦截器会覆盖 ThinkBoot 的默认配置,此时 `think-boot.auth.exclude-paths` 配置将不再生效。
**使用 Sa-Token 原生功能**:
ThinkBoot 完全兼容 Sa-Token 的所有原生功能,你可以直接使用:
```java
// 会话登录
StpUtil.login(userId);
// 判断是否登录
StpUtil.isLogin();
StpUtil.checkLogin();
// 获取登录账号 ID
StpUtil.getLoginId();
StpUtil.getLoginIdAsString();
StpUtil.getLoginIdAsLong();
// 获取 token 信息
StpUtil.getTokenValue();
StpUtil.getTokenTimeout();
// 注销登录
StpUtil.logout();
StpUtil.logout(userId); // 强制指定账号下线
StpUtil.kickout(userId); // 踢下线
StpUtil.replaced(userId); // 顶下线
// 角色权限校验(需要时自行配置)
@SaCheckRole("admin")
@SaCheckPermission("user:add")
```
**Sa-Token Session 会话**:
Sa-Token 提供三种类型的 Session,用于缓存高频读写数据:
```java
// 1. Account-Session(基于账号 ID 的会话)
StpUtil.getSession().set("user", user); // 写入数据
SysUser user = (SysUser) StpUtil.getSession().get("user"); // 读取数据
// 2. Token-Session(基于 Token 的会话)
StpUtil.getTokenSession().set("data", value); // 写入数据
Object data = StpUtil.getTokenSession().get("data"); // 读取数据
// 3. Custom-Session(自定义会话,以特定值作为 SessionId)
SaSessionCustomUtil.getSessionById("goods-10001").set("stock", 100);
```
> **注意**:SaSession 与 HttpSession 是**完全不同**的两个对象,请勿混用。使用 Sa-Token 时,请在任何情况下均使用 SaSession。
**Sa-Token 1.45.0 新功能**:
ThinkBoot 已升级到 Sa-Token 1.45.0,新增以下功能:
1. **重复登录处理策略** - 可选择踢人还是拦截
```java
// 在 application.yml 中配置
sa-token:
# 当发生重复登录时,是否踢人(true=踢人,false=拦截)
# 默认 true,即新登录踢掉旧登录
is-concurrent: true
```
2. **beforeAuth 前置函数** - 在认证之前执行自定义逻辑
```java
@Configuration
public class CustomSaTokenConfig implements WebMvcConfigurer {
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new SaInterceptor(handler -> {
SaRouter.match("/**").check(r -> StpUtil.checkLogin());
})
.setBeforeAuth(handle -> {
// 认证之前的自定义逻辑,如记录请求日志
System.out.println("请求路径:" + SaHolder.getRequest().getRequestPath());
})
).addPathPatterns("/**");
}
}
```
3. **注销时携带设备 ID** - 精确控制指定设备的注销
```java
// 注销指定设备
StpUtil.logout(userId, "PC");
StpUtil.logout(userId, "APP");
```
更多 Sa-Token 功能请参考官方文档:[https://sa-token.cc](https://sa-token.cc)
### think-boot-database
数据库模块,基于 MyBatis-Plus 实现。
**包含内容**:
- MyBatis-Plus 配置:分页、乐观锁、防全表更新
- 实体基类:`BaseEntity`(自动填充创建/更新时间)
- 分页查询:`PageQuery`
**框架增强配置**:
ThinkBoot 暴露了分页参数配置项,方便开发者调整:
```yaml
think-boot:
database:
pagination:
max-limit: 500 # 分页最大限制(默认 500)
overflow: true # 超出限制后是否溢出(默认 true)
```
**使用示例**:
```java
// 实体类
@Data
@EqualsAndHashCode(callSuper = true)
@TableName("sys_user")
public class User extends BaseEntity {
@TableId(type = IdType.ASSIGN_ID)
private Long id;
private String username;
private String nickname;
}
// Mapper
@Mapper
public interface UserMapper extends BaseMapper {
}
// Service
@Service
public class UserService extends ServiceImpl {
}
// Controller
@GetMapping("/users")
public R> list(PageQuery query) {
Page page = new Page<>(query.getCurrent(), query.getSize());
Page result = userService.page(page);
return R.ok(new PageResult<>(result));
}
```
> **注意**:框架不自动配置 `@MapperScan`,使用者需要自行配置 Mapper 扫描路径:
> ```java
> @SpringBootApplication
> @MapperScan(basePackages = {
> "com.yourpackage.mapper",
> "com.thinkboot.web.mapper"
> })
> public class Application {
> public static void main(String[] args) {
> SpringApplication.run(Application.class, args);
> }
> }
> ```
**数据源配置**:
单数据源配置(默认方式,开箱即用):
```yaml
spring:
datasource:
url: jdbc:mysql://localhost:3306/your_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
username: root
password: your_password
driver-class-name: com.mysql.cj.jdbc.Driver
```
多数据源配置(需要时切换):
```yaml
spring:
datasource:
dynamic:
primary: master # 默认数据源
strict: false # 严格模式:true-未匹配到数据源抛异常,false-未匹配使用默认数据源
datasource:
master: # 主库(写操作)
url: jdbc:mysql://localhost:3306/db1
username: root
password: root123
driver-class-name: com.mysql.cj.jdbc.Driver
slave: # 从库(读操作)
url: jdbc:mysql://localhost:3306/db2
username: root
password: root123
driver-class-name: com.mysql.cj.jdbc.Driver
```
**切换数据源示例**:
```java
@Service
public class UserService extends ServiceImpl {
// 使用从库查询
@DS("slave")
public List queryFromSlave() {
return list();
}
// 使用主库写入(默认)
public void saveUser(User user) {
save(user);
}
}
```
**支持的数据源类型**:
- MySQL(默认内置)
- PostgreSQL
- Oracle
- SQL Server
- 其他 MyBatis-Plus 支持的数据库
> **注意**:使用其他数据库时,需要在 `pom.xml` 中添加对应驱动依赖,并确保 `PaginationInnerInterceptor` 能自动识别数据库类型。
### think-boot-codegen
代码生成模块,基于 MyBatis-Plus Generator 封装。
**包含内容**:
- 代码生成器:`ThinkBootCodeGenerator`
- 使用示例:`CodeGeneratorExample`
**使用示例**:
在你的项目中创建代码生成器类:
```java
import com.baomidou.mybatisplus.annotation.IdType;
import com.thinkboot.codegen.ThinkBootCodeGenerator;
public class CodeGenerator {
public static void main(String[] args) {
new ThinkBootCodeGenerator()
// 数据库连接配置
.url("jdbc:mysql://localhost:3306/thinkboot?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai")
.username("root")
.password("root")
// 要生成的表名(可设置多个)
.tableName("sys_user", "sys_role", "sys_menu")
// 模块配置
.moduleName("system")
// 作者信息
.author("Your Name")
// 代码输出路径
.outputPath("D:/your-project/src/main/java")
// 忽略表前缀(sys_ 会被忽略,生成 User/Role/Menu)
.ignoreTablePrefix("sys_")
// 是否继承 BaseEntity
.useBaseEntity(true)
// 主键类型
.idType(IdType.ASSIGN_ID)
// 执行生成
.generate();
}
}
```
**生成的代码包括**:
- Entity(实体类):继承 BaseEntity,包含 Swagger 注解
- Mapper(数据访问层):继承 BaseMapper
- Service(业务逻辑接口):继承 IService
- ServiceImpl(业务逻辑实现):继承 ServiceImpl
- Controller(控制器):REST 风格
- Mapper.xml(MyBatis XML 映射文件)
**支持的配置项**:
| 配置项 | 说明 | 默认值 |
|--------|------|--------|
| url | 数据库连接 URL | - |
| username | 数据库用户名 | root |
| password | 数据库密码 | root |
| tableName | 要生成的表名 | - |
| moduleName | 模块名称 | - |
| author | 作者 | thinkboot |
| outputPath | 代码输出路径 | 当前目录 |
| parentPackage | 父包名 | com.thinkboot |
| ignoreTablePrefix | 忽略的表前缀 | sys_ |
| useBaseEntity | 是否继承 BaseEntity | false |
| useLogicDelete | 是否启用逻辑删除 | false |
| idType | 主键类型 | ASSIGN_ID |
### think-boot-redis
Redis 缓存模块。
**包含内容**:
- Redis 配置:JSON 序列化(使用 `@ConditionalOnMissingBean` 允许开发者覆盖原生 RedisTemplate)
- 工具类:`RedisUtils`
> **设计说明**:框架创建 JSON 序列化的 RedisTemplate Bean,同时使用 `@ConditionalOnMissingBean` 允许开发者覆盖。开发者仍可通过 `spring.data.redis.*` 原生配置项自定义连接等参数。
**使用示例**:
```java
@Autowired
private RedisUtils redisUtils;
// 字符串操作
redisUtils.set("key", "value", 3600);
String value = (String) redisUtils.get("key");
// Hash 操作
redisUtils.hSet("user:1", "name", "张三");
String name = (String) redisUtils.hGet("user:1", "name");
// 删除
redisUtils.delete("key");
```
### think-boot-cache
缓存抽象层模块,基于 Spring Cache 实现。
**包含内容**:
- Spring Cache 注解支持:`@Cacheable`、`@CachePut`、`@CacheEvict`
- Redis CacheManager 配置
- Jackson2JsonRedisSerializer 序列化
- 多缓存配置:default(1小时)、short(10分钟)、long(24小时)
**框架增强配置**:
ThinkBoot 暴露了缓存 TTL 配置项,方便开发者调整:
```yaml
think-boot:
cache:
ttl:
default-hours: 1 # 默认缓存时间(小时)
short-minutes: 10 # 短期缓存时间(分钟)
long-hours: 24 # 长期缓存时间(小时)
```
> **安全说明**:框架使用 `BasicPolymorphicTypeValidator` 替代不安全的 `LaissezFaireSubTypeValidator`,提升反序列化安全性。
**使用示例**:
```java
@Service
public class UserService extends ServiceImpl {
// 查询时缓存数据(1小时过期)
@Cacheable(value = "user", key = "#id")
public User getById(Long id) {
return super.getById(id);
}
// 更新时同步缓存
@CachePut(value = "user", key = "#user.id")
public User updateUser(User user) {
updateById(user);
return user;
}
// 删除时清除缓存
@CacheEvict(value = "user", key = "#id")
public void deleteUser(Long id) {
removeById(id);
}
// 使用不同过期时间的缓存(short = 10分钟)
@Cacheable(value = "short", key = "#code")
public String getSmsCode(String phone) {
// 生成并发送短信验证码
return generateCode();
}
}
```
**支持的注解**:
| 注解 | 说明 | 使用场景 |
|------|------|----------|
| `@Cacheable` | 查询时缓存 | 详情查询、列表查询 |
| `@CachePut` | 更新缓存 | 数据修改后同步缓存 |
| `@CacheEvict` | 清除缓存 | 数据删除时清除缓存 |
### think-boot-security
安全防护模块,提供 XSS 防护、接口幂等性、分布式锁等企业级安全特性。
**包含内容**:
- XSS 防护:自动过滤请求参数中的 XSS 攻击代码
- 接口幂等性:基于 Redis Token 机制,防止重复提交
- 分布式锁:基于 Redis SETNX + Lua 脚本,支持 SpEL 表达式
#### XSS 防护
**开箱即用,无需任何配置**,框架自动拦截以下攻击:
- `