mobile wallpaper 1mobile wallpaper 2mobile wallpaper 3mobile wallpaper 4mobile wallpaper 5mobile wallpaper 6
1274 字
3 分钟
Spring Cache 入门
2025-12-06
无标签

Spring Cache 入门教程:用注解轻松实现缓存(Redis为例子)#

在日常开发中,我们经常会遇到“重复查询数据库”的情况,比如查询用户信息、商品信息、文章列表等。
如果访问量大,这些操作会给数据库带来压力。

Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要加个注解就能实现缓存功能

Spring Cache 的使用也非常简单,只需要导入不同的依赖底层就能切换不同的缓存实现,如Redis,EHcache

下面我们通过几个简单的例子来入门 Spring Cache。


一.开启 Spring Cache#

1.导入Spring Cache的依赖

2.在Spring boot 的启动类上加这个注解@EnableCaching ,这样就开启了缓存功能。


二.常用注解(掌握这三个就够了)#

注解作用
@Cacheable用于方法查询。当传入的 key 在缓存中已有数据时,直接返回缓存结果,不执行方法体;若缓存不存在,则执行方法、获取结果并写入缓存,适用于“查多改少”的接口。
@CachePut无论缓存中是否存在都会执行方法体,将方法返回值放入缓存中并覆盖旧值。常用于更新、修改、保存数据时,确保数据库与缓存一致,不会跳过方法。
@CacheEvict用于移除缓存中的数据,可删除指定 key,也可通allEntries=true 清空整个缓存区域。适用于删除数据、更新列表数据后手动清理缓存等场景,保证缓存与数据库同步。

三个注解的参数写法总结(最常用)

注解必需参数常用参数示例
@Cacheablevaluekey, unless, condition@Cacheable(value = "user", key = "#id", unless = "#result == null") 如果返回结果 #result == null,就不写入缓存。
@CachePutvaluekey, unless, condition@Cacheable(value = “user”, key = “#id”, condition = “#id > 1000”) 只有当 id > 1000 时,Spring 才会去查缓存 / 写缓存。 否则直接执行方法,不用缓存。
@CacheEvictvaluekey, allEntries, beforeInvocation@CacheEvict(value = "user", key = "#id", beforeInvocation = true) 方法执行前立刻删除缓存,不管后面方法是否抛异常。

注解参数用于哪个注解作用
condition@Cacheable @CachePut @CacheEvict满足条件才执行缓存逻辑(执行前判断)
unless@Cacheable @CachePut方法执行后,如果条件为 true,则不缓存结果
allEntries@CacheEvict是否清空整个缓存空间
beforeInvocation@CacheEvict是否在方法调用前就清除缓存(默认是方法调用后)

1.@Cacheable —— 查询时使用#

注:是Springframework的这个

使用方法:

说明:程序执行到@Cacheable处会先去查询你的redis有无数据,如果无就执行getById这个方法并将数据存储到redis里面,如果有就直接从redis拿出数据,不执行方法。


2.@CachePut —— 修改时更新缓存#

也能这样写@CachePut(value = “user”, key = “#result.id”),区别就是一个是从方法参数取 id,一个是从返回对象取id,但要注意

使用 #result 必须保证方法返回的对象不是 null并且返回值里要包含 id

key的写法很多,这两种写法最常用。

说明:程序执行到 @CachePut 注解时,无论 redis 中是否已有缓存,都会先执行方法本身,执行完成后再把方法的返回结果更新到 redis 的指定 key 中。即:方法必定执行,并覆盖(或写入)缓存。


3.@CacheEvict —— 删除缓存#

基本用法:删除一个 key:

清空整个缓存区域:

说明:程序执行到 @CacheEvict 注解时,会根据配置的 key 从 redis 中删除对应的缓存数据。如果设置了 allEntries = true,则会清空当前缓存空间下的所有数据。默认在方法执行完成后删除缓存,也可以通过 beforeInvocation = true 实现在方法执行前删除。


三.对比,不用 Spring Cache(手写缓存) vs 使用 Spring Cache#


不用 Spring Cache(手写 Redis 逻辑)#

@Service
public class UserService {
@Autowired
private RedisTemplate<String, Object> redisTemplate;
@Autowired
private UserMapper userMapper;
public User getUserById(Long id) {
String key = "user:" + id;
// 1. 查询缓存
User user = (User) redisTemplate.opsForValue().get(key);
if (user != null) {
return user; // 2. 有缓存,直接返回
}
// 3. 无缓存,查数据库
user = userMapper.findById(id);
if (user != null) {
// 4. 写入缓存
redisTemplate.opsForValue().set(key, user, 1, TimeUnit.HOURS);
}
return user;
}
}

缺点:

每次都要写 key

要手动处理缓存过期时间

需要自己写“查 → 判断 → 回源 → 存”的模板逻辑

代码重复率高

容易漏写缓存逻辑导致不一致


使用 Spring Cache(自动处理缓存逻辑)#

@Service
public class UserService {
@Autowired
private UserMapper userMapper;
@Cacheable(value = "user", key = "#id")
public User getUserById(Long id) {
return userMapper.findById(id);
}
}

说明(自动完成刚才手写的逻辑):

先查缓存 user::id

如果有 → 直接返回,不执行方法

如果没有 → 执行方法查数据库

方法返回值自动写入 redis

优点:

一行注解自动实现读缓存

不需要自己写 redisTemplate

不需要写逻辑判断缓存是否存在

不需要自己写 key 拼接

不需要自己设置缓存过期时间(可全局配置)

更简洁、可读性强、可维护性高。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

Spring Cache 入门
https://csa.fur1na.top/posts/spring-cache-入门/
作者
fur1na
发布于
2025-12-06
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

封面
Sample Song
Sample Artist
封面
Sample Song
Sample Artist
0:00 / 0:00