Spring Cache
·
一、Spring Cache 核心概念
Spring Cache 是 Spring 框架提供的缓存抽象层,它不直接实现缓存,而是定义了一套统一的缓存操作接口,底层可以对接不同的缓存实现(如 Redis、Caffeine、Ehcache 等)。核心优势是:
- 基于注解,无需手写缓存逻辑,代码侵入性极低;
- 统一的 API,切换缓存实现只需改配置,无需改业务代码;
- 支持缓存的增、删、更新、失效等全生命周期管理。
核心注解
| 注解 | 作用 |
|---|---|
@EnableCaching | 开启缓存功能(必须加在配置类 / 启动类上) |
@Cacheable | 方法执行前先查缓存,有则返回缓存值,无则执行方法并将结果存入缓存 |
@CachePut | 执行方法后将结果存入缓存(常用于更新操作,不会跳过方法执行) |
@CacheEvict | 移除缓存(常用于删除操作) |
@Caching | 组合多个缓存注解(如同时更新 + 删除) |
@CacheConfig | 类级别注解,统一配置缓存名称、keyGenerator 等,简化方法级注解配置 |
二、快速上手:Spring Cache + Redis 实战
以最常用的 Redis 作为缓存实现,演示完整使用流程。
1. 前置依赖(Maven)
<!-- Spring Cache 核心依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<!-- Redis 依赖(缓存实现) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- 可选:Jackson 序列化,解决 Redis 存储对象乱码问题 -->
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
2. 配置 Redis 与缓存(application.yml)
spring:
# Redis 配置
redis:
host: localhost
port: 6379
password: 123456 # 无密码则省略
database: 0
# 缓存配置
cache:
type: redis # 指定缓存类型为 Redis
redis:
time-to-live: 3600000 # 缓存过期时间(毫秒),1小时
key-prefix: "user:" # 缓存key前缀,方便区分
use-key-prefix: true # 启用前缀
3. 开启缓存(启动类)
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@EnableCaching // 必须开启缓存注解功能
public class CacheDemoApplication {
public static void main(String[] args) {
SpringApplication.run(CacheDemoApplication.class, args);
}
}
4. 业务代码中使用缓存
以用户查询、更新、删除为例:
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
@Service
public class UserService {
// 模拟数据库存储
private Map<Long, User> userMap = new HashMap<>();
/**
* 查询用户:优先查缓存,无则查"数据库"并缓存
* @param id 用户ID
* @return 用户信息
*/
@Cacheable(value = "userCache", key = "#id")
// value:缓存名称(必填);key:缓存键(SpEL表达式,#id表示方法参数id)
public User getUserById(Long id) {
//先查缓存,无则查"数据库"并缓存,打印下面语句,如果缓存存在则不会执行下面打印语句
System.out.println("执行数据库查询,并缓存,id=" + id); // 用于验证是否走缓存
return userMap.get(id);
}
/**
* 更新用户:执行方法后更新缓存(方法一定会执行)
* @param user 更新后的用户信息
* @return 更新后的用户
*/
@CachePut(value = "userCache", key = "#user.id")
public User updateUser(User user) {
System.out.println("执行数据库更新,id=" + user.getId());
userMap.put(user.getId(), user);
return user;
}
/**
* 删除用户:移除对应缓存
* @param id 用户ID
*/
@CacheEvict(value = "userCache", key = "#id")
public void deleteUser(Long id) {
System.out.println("执行数据库删除,id=" + id);
userMap.remove(id);
}
// 模拟用户实体类
public static class User {
private Long id;
private String name;
private Integer age;
// 省略getter/setter/构造方法
}
}
5. 测试验证
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
public class CacheTest {
@Autowired
private UserService userService;
@Test
public void testCache() {
// 1. 首次查询:无缓存,执行数据库查询
User user1 = userService.getUserById(1L);
// 2. 二次查询:有缓存,不执行数据库查询
User user2 = userService.getUserById(1L);
// 3. 更新用户:执行方法并更新缓存
User updateUser = new User(1L, "张三", 25);
userService.updateUser(updateUser);
// 4. 删除用户:移除缓存
userService.deleteUser(1L);
}
}
三、关键细节说明
- SpEL 表达式(缓存 key):
#id:方法参数 id;#user.id:方法参数 user 的 id 属性;#root.methodName:当前方法名;#root.args[0]:方法第一个参数。
- 缓存失效场景:
- 手动调用
@CacheEvict; - 缓存达到过期时间(如配置的 1 小时);
- 底层缓存实现自身的清理策略(如 Redis 内存淘汰)。
- 手动调用
- 自定义缓存配置:如果需要自定义 Redis 序列化(解决对象乱码),可添加配置类:
import org.springframework.cache.annotation.EnableCaching; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.cache.RedisCacheConfiguration; import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializationContext; import org.springframework.data.redis.serializer.StringRedisSerializer; @Configuration @EnableCaching public class CacheConfig { @Bean public RedisCacheConfiguration redisCacheConfiguration() { return RedisCacheConfiguration.defaultCacheConfig() // key 序列化 .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(new StringRedisSerializer())) // value 序列化(JSON格式) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())) .entryTtl(java.time.Duration.ofHours(1)); // 过期时间 } }
总结
- 核心定位:Spring Cache 是缓存抽象层,通过注解简化缓存逻辑,底层可对接 Redis/Caffeine 等实现;
- 核心注解:
@EnableCaching开启缓存,@Cacheable查缓存,@CachePut更新缓存,@CacheEvict删除缓存; - 关键配置:使用 Redis 时需配置序列化方式(避免乱码)和过期时间,保证缓存数据的有效性和可读性。
更多推荐


所有评论(0)