Spring Cache:简化缓存管理的抽象框架

Spring Cache

Spring Cache是Spring框架提供的缓存抽象层,通过注解和自动化配置,简化应用中对缓存的操作,支持多种缓存实现(如Redis、Ehcache、Caffeine)。

1. 核心特性

  • **声明式缓存:**通过注解(如@Cacheable、@CacheEvict)声明缓存行为,无需手动编写缓存逻辑。
  • **多缓存实现支持:**兼容Redis、Ehcache、Caffeine等缓存工具,通过统一接口切换实现。
  • **与Spring无缝集成:**基于AOP动态代理,拦截方法调用自动处理缓存。
  • **灵活的缓存策略:**支持条件缓存(condition)、缓存键生成(key)、缓存过期等配置。

2. 核心注解

| 注解 | 作用 | 常用参数 | 示例 |
| @EnableCaching | 开启缓存注解功能,通常加在启动类上 | | |
| @Cacheable | 方法结果缓存。在方法执行前先查询缓存中是否有数据,如果有数据则直接返回缓存数据;如果没有缓存数据,调用方法并将方法返回值放到缓存中 | value(缓存名)、key(键)、condition(条件) | 缓存数据库查询结果 |
| @CachePut | 更新缓存,将方法的返回值放到缓存中 | value(缓存名)、key(键)、condition(条件) | 数据更新后刷新缓存 |

@CacheEvict 删除缓存,将一条或多条数据从缓存中删除 allEntries(清空所有键)、beforeInvocation(执行前删除) 数据清除时删除缓存

1. @Cacheable:

**作用:**标记方法的结果需要被缓存。当方法被调用时,先检查缓存是否存在对应键值,若存在则直接返回缓存值,否则执行方法并将结果存入缓存。

**使用场景:**查询操作(如数据库查询、复杂计算等)。

示例:

java 复制代码
@Cacheable(value = "userCache", key = "#userId", condition = "#userId != null")
public User getUserById(Long userId) {
    return userRepository.findById(userId).orElse(null);
}

2. @CachePut:

**作用:**更新缓存。无论缓存是否存在,都会执行方法,并将结果更新到缓存中。

**适用场景:**新增或更新操作(如更新用户信息后同步缓存)。

示例:

java 复制代码
@CachePut(value = "userCache", key = "#user.id")
public User updateUser(User user) {
    return userRepository.save(user);
}

3. @CacheEvict

**作用:**删除缓存。根据条件清除指定键或整个缓存区的数据。

**适用场景:**删除操作(如用户删除后清理缓存)。

示例:

java 复制代码
@CacheEvict(value = "userCache", key = "#userId")
public void deleteUser(Long userId) {
    userRepository.deleteById(userId);
}

// 清空整个缓存区
@CacheEvict(value = "userCache", allEntries = true)
public void clearAllUserCache() {}

3.使用步骤(以Redis为例)

添加依赖:

XML 复制代码
<!-- Spring Boot Starter 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>

配置缓存类型与Redis:

XML 复制代码
# application.properties
spring.cache.type=redis
spring.redis.host=localhost
spring.redis.port=6379
# 可选:设置缓存过期时间(单位:毫秒)
spring.cache.redis.time-to-live=60000

**启用缓存:**在启动类添加@EnableCaching

java 复制代码
@SpringBootApplication
@EnableCaching
public class MyApp { ... }

在Service层使用注解:

java 复制代码
// 仅当参数id>10时缓存
@Cacheable(value = "users", condition = "#id > 10")

// 结果不为null时缓存
@Cacheable(value = "users", unless = "#result == null")

4. 缓存键与条件控制

自定义缓存键(SpEL表达式)

java 复制代码
@Cacheable(value = "orders", key = "#userId + ':' + #status")
public List<Order> getOrdersByUserAndStatus(Long userId, String status) { ... }

条件缓存(condition和unless)

java 复制代码
// 仅当参数id>10时缓存
@Cacheable(value = "users", condition = "#id > 10")

// 结果不为null时缓存
@Cacheable(value = "users", unless = "#result == null")

5. 适用场景

  1. **高频读低频写:**如商品详情页、用户信息查询。
  2. **耗时计算:**缓存复杂计算结果(如报表生成)。
  3. **API限流:**缓存接口调用次数。
  4. **会话管理:**分布式环境下用户状态缓存。

Spring Cache通过简化缓存逻辑与代码解耦,显著提升了开发效率。结合Redis等高性能缓存工具,能够轻松应对高并发场景。

相关推荐
岁忧4 分钟前
(LeetCode 每日一题) 1865. 找出和为指定值的下标对 (哈希表)
java·c++·算法·leetcode·go·散列表
YuTaoShao7 分钟前
【LeetCode 热题 100】240. 搜索二维矩阵 II——排除法
java·算法·leetcode
考虑考虑1 小时前
JDK9中的dropWhile
java·后端·java ee
想躺平的咸鱼干1 小时前
Volatile解决指令重排和单例模式
java·开发语言·单例模式·线程·并发编程
hqxstudying2 小时前
java依赖注入方法
java·spring·log4j·ioc·依赖
·云扬·2 小时前
【Java源码阅读系列37】深度解读Java BufferedReader 源码
java·开发语言
春生野草2 小时前
关于SpringMVC的整理
spring
Bug退退退1233 小时前
RabbitMQ 高级特性之重试机制
java·分布式·spring·rabbitmq
小皮侠3 小时前
nginx的使用
java·运维·服务器·前端·git·nginx·github
Zz_waiting.3 小时前
Javaweb - 10.4 ServletConfig 和 ServletContext
java·开发语言·前端·servlet·servletconfig·servletcontext·域对象