@Cacheable、@CachePut 和 @CacheEvict 三个注解的区别

在 Spring 框架中,@Cacheable@CachePut 和 @CacheEvict 是三个与缓存管理相关的核心注解,它们与 Redis 等缓存中间件结合使用时,可以显著提升应用性能。以下是它们的核心区别和适用场景:


1. @Cacheable

作用
在方法执行前检查缓存,如果缓存中存在对应结果,直接返回缓存值,跳过方法执行;若不存在,则执行方法并将返回值存入缓存。

适用场景

  • 查询操作(例如根据 ID 查询用户信息)。

  • 适用于结果稳定、不频繁变更的数据。

关键参数

  • value/cacheNames:缓存名称(如 "users")。

  • key:缓存的键(支持 SpEL 表达式)。

  • condition/unless:缓存条件(如 condition="#id > 10")。

示例

@Cacheable(value = "users", key = "#id")
public User getUserById(Long id) {
    // 查询数据库
    return userRepository.findById(id);
}

2. @CachePut

作用
无论缓存是否存在,始终执行方法,并将返回值更新到缓存中。适用于需要强制刷新缓存的场景。

适用场景

  • 更新操作(例如修改用户信息后同步更新缓存)。

  • 需要确保缓存与数据库数据一致。

关键参数
与 @Cacheable 相同,但需确保 key 的生成逻辑与 @Cacheable 一致,否则可能导致缓存不一致。

示例

@CachePut(value = "users", key = "#user.id")
public User updateUser(User user) {
    // 更新数据库
    userRepository.update(user);
    return user; // 更新后的结果存入缓存
}

3. @CacheEvict

作用
删除指定缓存条目或清空整个缓存。支持在方法调用触发。

适用场景

  • 删除操作(例如删除用户后清除缓存)。

  • 数据变更后需要清理旧缓存(如批量更新后清空列表缓存)。

关键参数

  • allEntries:是否清空整个缓存(默认为 false,仅删除 key 对应的条目)。

  • beforeInvocation:是否在方法执行前删除缓存(默认为 false,方法执行后删除)。

示例

@CacheEvict(value = "users", key = "#id")
public void deleteUser(Long id) {
    userRepository.deleteById(id);
}

// 清空整个缓存
@CacheEvict(value = "users", allEntries = true)
public void refreshAllUsers() {
    // 无需实际逻辑,仅触发缓存清理
}

三者的核心区别

注解是否执行方法体缓存行为典型场景
@Cacheable缓存命中时跳过读取缓存或写入新结果查询(幂等操作)
@CachePut始终执行强制更新缓存更新(非幂等)
@CacheEvict通常执行删除缓存条目或清空整个缓存删除或清理缓存

注意事项

  1. 键的一致性
    @Cacheable 和 @CachePut 的 key 生成逻辑必须一致,否则更新后可能无法覆盖旧缓存。

  2. 事务与缓存的顺序
    默认情况下,缓存操作在方法执行后触发。若方法有事务,需确保缓存操作在事务提交后执行(可通过 @Transactional 配置)。

  3. 条件过滤
    使用 condition 和 unless 避免缓存无效数据(如 unless="#result == null")。

  4. 分布式锁
    在高并发场景下,结合分布式锁(如 Redis 的 RedLock)避免缓存击穿或雪崩。

Spring框架通过Spring Cache提供了一套强大的缓存体系,可以轻松地实现缓存数据,提高应用程序的性能。Spring框架提供了三个主要的注解来实现缓存:@Cacheable@CachePut@CacheEvict@Cacheable注解用于将方法的结果缓存起来,以便在下次请求时,如果参数相同,则可以直接从缓存中获取结果,而不需要重新计算。该注解适用于如果计算结果比较耗时,或者需要从数据库或其他外部资源中提取数据的情况。 @CachePut注解用于更新缓存中的数据。它与@Cacheable注解类似,但不同的是,它总是更新缓存数据,而不管缓存中是否已经存在该key的值。所以,可以使用这个注解来更新缓存中的数据。 @CacheEvict注解用于从缓存中删除数据。它在需要删除缓存数据的情况下使用。它可以删除指定的key对应的缓存,也可以清空所有缓存数据。 这三个注解都有一个可选参数Named:如果指定了该参数,则缓存将使用指定的名称使用。如果未指定,则使用默认的名称。可以使用不同名称的缓存来存储不同类型的数据,并使用不同的缓存策略来控制它们的存储方式。 除了Spring自带的缓存提供者之外,还可以使用其他的缓存提供者,如Ehcache、Redis、Memcached等等。在使用缓存时,需要注意的是,不同的缓存提供者之间可能会有不同的限制性能差异。因此,必须根据实际情况选择最适合的缓存提供者缓存策略,以获取最好的性能可靠性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

dushky

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值