Spring Cache讲解

目录

一、Spring Cache是什么

Spring CacheSpring 框架提供的缓存抽象层,让你可以轻松地 在应用程序中添加缓存功能 ,而无需关心底层缓存实现细节。

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

1、核心优势

特点 说明
声明式缓存 使用注解即可实现缓存功能
抽象层设计 支持多种缓存实现(RedisEhCacheGuava等)
与 Spring 集成 完美集成 Spring 生态
方法级缓存 基于方法返回值进行缓存
缓存策略灵活 支持条件缓存、同步刷新等

2、基本使用

1. 添加依赖

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>

2. 启用缓存

java 复制代码
@SpringBootApplication
@EnableCaching  // 启用缓存支持
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

二、核心注解详解

1、@EnableCaching

@EnableCachingSpring 框架中的一个注解,用于启用 Spring 的缓存支持 。当你在配置类上添加此注解时,Spring 会创建一个缓存相关的切面,以拦截带有缓存注解的方法调用。

主要作用

  • 启用缓存机制:在 Spring 应用中激活缓存功能
  • 自动配置 :根据项目依赖自动配置合适的 CacheManager
  • 注解驱动 :支持使用 @Cacheable, @CacheEvict, @CachePut 等注解
java 复制代码
@Configuration
@EnableCaching
public class CacheConfig {
    
    // Spring Boot 会自动配置合适的 CacheManager
    // 手动配置示例:
    @Bean
    public CacheManager cacheManager() {
        return new ConcurrentMapCacheManager("users", "products");
    }
}

2、@Cacheable

@CacheableSpring 缓存中最核心的注解,用于标记方法的返回结果应该被缓存。
解释:在方法执行前先查询缓存中是否有数据,如果有数据,则直接返回缓存数据;如果没有缓存数据,调用方法并将方法返回值放到缓存中

java 复制代码
    @GetMapping
    @Cacheable(value = "userCache",key = "#id")
    public User getById(Long id){
        User user = userMapper.getById(id);
        return user;
    }

@Cacheable(value = "userCache",key = "#id")value的属性是存在redis中的名称,存到redis的时候会创建value::keyredis中。
@Cacheable(value = "userCache",key = "#id")中的key是和value代码作为::后面的参数。

我们查看源码的时候可以看到,如下的情况:

key可以用多种情况展示,参数名称,当有多个参数的时候可以使用#p0,#p1,单一参数的时候可以使用#root,参数名称等多种情况。
数据验证

Debug运行项目,查看项目的执行流程。

使用Swagger进行代码调试:http://localhost:8888/doc.html#/home

当数据没有存到redis时候,会直接查询数据库,如果存到redis之后会直接从redis中查找,并且不经过代码直接返回。

redis没有存储信息:

接口会直接进入到代码当中:

返回结果:

redis中的结果:

现在redis中已经有了key值,我们再执行以下逻辑(根据耗时可以看出直接从redis中获取了):

3、@CachePut

@CachePut 注解用于更新缓存,它总是会执行方法体,并将返回结果放入缓存中。与 @Cacheable 不同的是,无论缓存中是否已存在,都会执行方法并更新缓存。

参数详解

参数 说明 示例
value/cacheNames 缓存名称 "users"
key 缓存键 #user.id, #result.id
keyGenerator 键生成器 "customKeyGenerator"
cacheManager 缓存管理器 "redisCacheManager"
cacheResolver 缓存解析器 "customResolver"
condition 执行条件 #user != null
unless 排除条件 #result == null
参数使用方法:
java 复制代码
    @PostMapping
    @CachePut(value = "userCache",key = "#user.id")
    public User save(@RequestBody User user){
        userMapper.insert(user);
        return user;
    }

@CachePut(value = "userCache",key = "#user.id"),可以根据user参数进行解析出来。

数据验证:

接口方法如下:

接口调试方法如下:

方法进入接口中:

结果如下:

4、@CacheEvict

@CacheEvict 用于清除缓存中的数据 。当数据发生变化(删除、更新)时,需要清除旧缓存,以保证数据一致性。
参数特征

参数 说明 默认值 示例
value/cacheNames 缓存名称 - "users"
key 要清除的缓存键 #id, #user.id
allEntries 是否清除所有条目 false true
beforeInvocation 调用前还是调用后清除 false true
condition 清除条件 #id != null
keyGenerator 键生成器 "customKeyGenerator"
cacheManager 缓存管理器 "redisCacheManager"
cacheResolver 缓存解析器 "customResolver"

接口方法1:

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

接口方法2:

java 复制代码
    @CacheEvict(value = "userCache",allEntries = true)
	@DeleteMapping("/delAll")
    public void deleteAll(){
        userMapper.deleteAll();
    }

,key = "#id"是删除单个keyallEntries=true的时候是删除所有的key

运行结果:

相关推荐
wjhx5 小时前
QT中对蓝牙权限的申请,整理一下
java·数据库·qt
一个有梦有戏的人5 小时前
Python3基础:进阶基础,筑牢编程底层能力
后端·python
YCY^v^5 小时前
JeecgBoot 项目运行指南
java·学习
人间打气筒(Ada)5 小时前
jenkins基于Pipeline发布项目
java·pipeline·jenkins·流水线·ci·cd·cicd
爬山算法5 小时前
Hibernate(88)如何在负载测试中使用Hibernate?
java·后端·hibernate
自不量力的A同学5 小时前
Solon AI v3.9 正式发布:全能 Skill 爆发
java·网络·人工智能
万岳科技系统开发5 小时前
食堂采购系统源码库存扣减算法与并发控制实现详解
java·前端·数据库·算法
独断万古他化5 小时前
【Spring 原理】Bean 的作用域与生命周期
java·后端·spring
*小海豚*5 小时前
在linux服务器上DNS正常,但是java应用调用第三方解析域名报错
java·linux·服务器
我爱加班、、5 小时前
Websocket能携带token过去后端吗
前端·后端·websocket