【Spring全家桶】Spring Cache 深度解析:一行注解实现缓存自动化

【Spring全家桶】Spring Cache 深度解析:一行注解实现缓存自动化

一、 为什么要使用 Spring Cache?

在传统的缓存开发中(如使用 Redis),我们需要在业务代码中手动编写逻辑:先查询缓存,如果没有再查询数据库,最后把结果放入缓存。这种做法会导致大量重复代码 ,且缓存逻辑与业务逻辑高度耦合

Spring Cache 通过 AOP(面向切面编程) 技术,将缓存逻辑从业务中剥离出来。你只需要在方法上加上简单的注解,即可实现缓存功能。


二、 核心架构与原理

Spring Cache 的核心思想是:在方法执行前检查缓存,执行后更新缓存。

  • CacheManager:缓存管理器,用于管理各种缓存组件(如 RedisCacheManager, EhCacheManager)。
  • Cache:缓存接口,定义了缓存的具体操作。

三、 快速上手:Spring Boot 整合 Redis 缓存

1. 添加依赖

pom.xml 中引入 Redis 缓存启动器:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

2. 开启缓存支持

在 Spring Boot 启动类上添加 @EnableCaching 注解:

java 复制代码
@SpringBootApplication
@EnableCaching // 开启缓存功能
public class CacheApplication {
    public static void main(String[] args) {
        SpringApplication.run(CacheApplication.class, args);
    }
}

3. 在 Service 层使用注解

这是 Spring Cache 最核心的部分,主要使用以下三个注解:

① @Cacheable:触发查询缓存

常用于查询操作。先看缓存有没有,有则直接返回;没有则执行方法并存入缓存。

java 复制代码
@Cacheable(value = "pet", key = "#id")
public PetBean getPetById(Integer id) {
    System.out.println("查询数据库...");
    return petDao.findById(id);
}
② @CachePut:更新缓存

常用于新增或修改操作。方法一定会执行,并将结果同步到缓存中。

java 复制代码
@CachePut(value = "pet", key = "#pet.id")
public PetBean updatePet(PetBean pet) {
    petDao.update(pet);
    return pet;
}
③ @CacheEvict:清除缓存

常用于删除操作。

java 复制代码
@CacheEvict(value = "pet", key = "#id")
public void deletePet(Integer id) {
    petDao.deleteById(id);
}

四、 常用注解属性详解

属性 含义 示例
value/cacheNames 缓存名称(相当于 Redis 的前缀) value = "user"
key 缓存的 key,支持 SpEL 表达式 key = "#user.id"
condition 满足条件时才缓存 condition = "#id > 10"
unless 否定缓存(满足条件时不缓存) unless = "#result == null"

五、 避坑指南:Spring Cache 失效的场景

很多初学者会遇到"加了注解但缓存不生效"的问题,通常是以下原因:

  1. 内部调用 :同一个类中,A 方法调用加了缓存注解的 B 方法,缓存会失效。
    • 原因:Spring Cache 是基于 AOP 代理的,内部调用不经过代理类。
  2. 方法非 public :缓存注解只能用于 public 方法。
  3. 结果未实现序列化 :如果使用 Redis 存储,存入的对象必须实现 java.io.Serializable 接口。

六、 进阶配置:自定义过期时间

默认情况下 Redis 缓存是永久有效的。我们可以通过配置 RedisCacheConfiguration 来设置过期时间:

java 复制代码
@Configuration
public class MyCacheConfig {
    @Bean
    public RedisCacheConfiguration redisCacheConfiguration() {
        return RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(30)) // 设置缓存过期时间 30 分钟
                .disableCachingNullValues();     // 不缓存空值
    }
}

七、 总结

Spring Cache 极大地简化了缓存开发,让我们可以专注于业务逻辑。在实际项目中,建议遵循以下原则:

  • 查询多、修改少的数据最适合使用缓存。
  • 一致性要求极高的数据慎用缓存。
  • 合理设置过期时间,防止 Redis 被冷数据撑爆。

下一篇预告:

我们将探讨 Spring Cache 如何配合 Jackson 解决缓存乱码问题 。如果你觉得这篇教程对你有帮助,欢迎 点赞、收藏、关注

作者: [CodeToGym]

相关推荐
新新学长搞科研11 小时前
第五届电子、集成电路与通信技术国际学术会议(EICCT 2026)
运维·人工智能·自动化·集成测试·信号处理·集成学习·电气自动化
森林里的程序猿猿12 小时前
Spring Aop底层源码实现(一)
java·后端·spring
阿达_优阅达12 小时前
告别手工对账:xSuite 如何帮助 SAP 企业实现财务全流程自动化?
服务器·数据库·人工智能·自动化·sap·企业数字化转型·xsuite
攒了一袋星辰12 小时前
SequenceGenerator高并发有序顺序号生成中间件 - 架构设计文档
java·后端·spring·中间件·架构·kafka·maven
renhongxia113 小时前
多模态融合驱动下的具身学习机制研究
运维·学习·机器人·自动化·知识图谱
大傻^14 小时前
LangChain4j Spring Boot Starter:自动配置与声明式 Bean 管理
java·人工智能·spring boot·spring·langchain4j
yhole14 小时前
springboot 修复 Spring Framework 特定条件下目录遍历漏洞(CVE-2024-38819)
spring boot·后端·spring
大傻^14 小时前
Spring AI 2.0 MCP 协议实战:Model Context Protocol SDK 与多服务器编排
服务器·人工智能·spring
Chengbei1114 小时前
Chrome浏览器渗透利器支持原生扫描!JS 端点 + 敏感目录 + 原型污染自动化检测|VulnRadar
javascript·chrome·安全·web安全·网络安全·自动化·系统安全
l软件定制开发工作室14 小时前
Spring开发系列教程(34)——打包Spring Boot应用
java·spring boot·后端·spring·springboot