SpringBoot详解整合Spring Cache如何实现Redis缓存流程

1、简介 Spring Cache 是一个框架,实现了基于注解的缓存功能,只需要简单地加一个注解,就能实现缓存功能。 Spring Cache 提供了一层抽象,

1、简介

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

Spring Cache 提供了一层抽象,底层可以切换不同的cache实现。

具体就是通过 CacheManager 接口来统一不同的缓存技术。

CacheManager 是 Spring 提供的各种缓存技术抽象接口,这是默认的缓存技术,是缓存在Map中的,这也说明当服务挂掉的时候,缓存的数据就没了。

针对不同的缓存技术需要实现不同的 CacheManager

CacheManager描述
EhCacheCacheManager使用 EhCache 作为缓存技术
GuavaCacheManager使用 Google 的 GuavaCache 作为缓存技术
RedisCacheManager使用 Redis 作为缓存技术

2、常用注解

在 Spring Boot 项目中,使用缓存技术只需在项目中导入相关缓存技术的依赖包,并在启动类上使用 @EnableCaching 开启缓存支持即可。例如,使用 Redis 作为缓存技术,只需要导入 Spring data Redis 的 maven 坐标即可。常用的注解有如下几个:

注解说明
@EnableCaching开启缓存注解功能
@Cacheable在方法执行前 spring 先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中
@CachePut将方法的返回值放到缓存中
@CacheEvict将一条或多条数据从缓存中删除

2.1、@EnableCaching

该注解的主要功能就是开启缓存注解的功能,让 Spring Cache 中的其他注解生效。使用方式也十分简单,直接将其加在项目的启动类上方即可。

@Slf4j
@SpringBootApplication
@EnableCaching
public class CacheDemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(CacheDemoApplication.class, args);
        log.info("项目启动成功...");
    }
}

2.2、@Cacheable

@Cacheable注解主要是在方法执行前 先查看缓存中是否有数据。如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中。

注解中的参数传递主要使用的是**SpEL(Spring Expression Language)**对数据进行获取传递,这有点类似于JSP中的EL表达式,常用方式如下几种:

  • “#p0”:获取参数列表中的第一个参数。其中的“#p”为固定写法,0为下标,代表第一个;
  • “#root.args[0]”:获取方法中的第一个参数。其中0为下标,代表第一个。
  • “#user.id”:获取参数 user 的 id 属性。注意的是这里的 user 必须要和参数列表中的参数名一致
  • “#result.id”:获取返回值中的 id 属性。

来自Spring Cache源码:Spring Expression Language (SpEL) expression used for making the method

@Cacheable注解中有几种常用的属性可进行需求性设置:

  • value:缓存的名称,每个缓存名称下面可以有多个 key
  • key:缓存的key。
  • condition:条件判断,满足条件时对数据进行缓存,值得注意的是该参数在Redis中无效
  • unless:条件判断,满足条件时则不对数据进行缓存,Redis中可使用该参数替代condition
/**
 * @description 通过id获取用户信息
 * @author xBaozi
 * @date 14:23 2022/7/3
 **/
@Cacheable(value = "userCache", key = "#id", unless = "#result == null")
@GetMapping("/{id}")
public User getById(@PathVariable Long id) {
    User user = userService.getById(id);
    return user;
}

2.3、@CachePut

@CachPut注解主要是将方法的返回值放到缓存中。这里同样是使用SpEL获取数据,常用的属性如下:

  • value:缓存的名称,每个缓存名称下面可以有多个 key
  • key:缓存的key。
  • condition:条件判断,满足条件时对数据进行缓存,值得注意的是该参数在Redis中无效
  • unless:条件判断,满足条件时则不对数据进行缓存,Redis中可使用该参数替代condition
/**
 * @description 新增用户信息并返回保存的信息
 * @author xBaozi
 * @date 14:38 2022/7/3
 **/
@CachePut(value = "userCache", key = "#user.id")
@PostMapping
public User save(User user) {
    userService.save(user);
    return user;
}

2.4、@CacheEvict

@CacheeEvict主要是将一条或多条数据从缓存中删除,同样使用SpEL获取数据,常用的属性如下:

  • value:缓存的名称,每个缓存名称下面可以有多个 key
  • key:缓存的key。
  • condition:条件判断,满足条件时对数据进行缓存,值得注意的是该参数在Redis中无效
  • unless:条件判断,满足条件时则不对数据进行缓存,Redis中可使用该参数替代condition
/**
 * @description 更新用户信息
 * @author xBaozi
 * @date 14:41 2022/7/3
 **/
@CacheEvict(value = "userCache", key = "#result.id")
@PutMapping
public User update(User user) {
    userService.updateById(user);
    return user;
}

3、使用Redis当作缓存产品

因为 Spring 默认的缓存技术无法持久化保存缓存数据,即服务挂了缓存也挂了,因此就需要使用Redis进行操作(其实也是因为学习了Redis)

前面的SpringBoot整合Redis缓存验证码里面有记录着一些Redis的基本操作。

3.1、坐标导入

导入 maven 坐标:spring-boot-starter-data-redis、spring-boot-starter-cache

<!--Spring Data Redis-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--Spring Cache-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>

3.2、yml配置

spring:
  redis:
    host: localhost
    port: 6379
    password: 123456
    database: 0
    cache:
        redis:
            time-to-live: 1800000 # 设置缓存有效期

3.3、开启注解功能

在启动类 com/itheima/CacheDemoApplication.java 上加入 @EnableCaching 注解,开启缓存注解功能

@Slf4j
@SpringBootApplication
@ServletComponentScan
@EnableCaching
public class ReggieApplication {
    public static void main(String[] args) {
        SpringApplication.run(ReggieApplication.class, args);
        log.info("springBoot项目启动成功……");
    }
}

3.4、使用@Cacheable

这里提一下有个坑就是使用的缓存时,返回值必须实现 Serializable 序列化接口,否则将会报错。

这是因为在 NoSql 数据库中,并没有与我们 Java 基本类型对应的数据结构,所以在往 NoSql 数据库中存储时,我们就必须将对象进行序列化,同时在网络传输中我们要注意到两个应用中 javabean 的 serialVersionUID 要保持一致,不然就不能正常的进行反序列化。

/**
 * @description 新增套餐信息
 * @author xBaozi
 * @date 17:55 2022/5/13
 * @param setmealDto    需要新增套餐的数据
 **/
@CacheEvict(value = "setmealCache",allEntries = true)
@PostMapping
public Result<String> save(@RequestBody SetmealDto setmealDto) {
    log.info("套餐信息为{}", setmealDto);
    setmealService.saveWithDish(setmealDto);
    return Result.success("套餐" + setmealDto.getName() + "新增成功");
}

3.5、使用@CacheEvict

这里用到了一个新属性allEntries,其是boolean类型,表示是否需要清除缓存中的所有元素。默认为false,表示不需要。当指定了 allEntries 为 true 时,Spring Cache将忽略指定的 key。有的时候我们需要 Cache 一下清除所有的元素,这比一个一个清除元素更有效率。

/**
 * @description 更新套餐信息并更新其关联的菜品
 * @author xBaozi
 * @date 11:28 2022/5/14
 * @param setmealDto    需要更新的套餐信息
 **/
@CacheEvict(value = "setmealCache",allEntries = true)
@PutMapping
public Result<String> updateWithDish(@RequestBody SetmealDto setmealDto) {
    log.info(setmealDto.toString());
    setmealService.updateWithDish(setmealDto);
    return Result.success("套餐修改成功");
}

4、测试

代码编写完成之后,重启工程,然后访问后台管理系统,对套餐数据进行新增以及删除,而后观察Redis中的数据发现写的代码是能正常跑到!成功!

到此这篇关于SpringBoot详解整合Spring Cache实现Redis缓存流程的文章就介绍到这了,更多相关SpringBoot Redis缓存内容请搜索好代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持好代码网!

您可能有感兴趣的文章
在SpringBoot中如何使用MongoDB完成数据存储

SpringBoot整合redis及mongodb的详细过程

MongoDB快速入门及其SpringBoot实战好代码教程

Spring Boot整合 NoSQL 数据库 Redis详解

SpringBoot+Redis执行lua脚本的5种方式总结