java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > @Cacheable、@CachePut和@CacheEvict区别

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

作者:dushky

@Cacheable、@CachePut和@CacheEvict是Spring框架中的核心缓存注解,分别用于查询、更新和删除缓存操作,@Cacheable在缓存命中时跳过方法执行;@CachePut强制执行并更新缓存;@CacheEvict删除或清空缓存,注意事项包括键的一致性、事务处理和条件过滤等

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

以下是它们的核心区别和适用场景:

@Cacheable

作用

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

适用场景

关键参数

示例

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

@CachePut

作用

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

适用场景

关键参数

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

示例

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

@CacheEvict

作用

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

适用场景

关键参数

示例

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

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

三者的核心区别

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

注意事项

键的一致性

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

事务与缓存的顺序

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

条件过滤

使用 condition 和 unless 避免缓存无效数据(如 unless="#result == null")。

分布式锁

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

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文