【Spring】Spring Cache 基于注解的缓存操作(包含使用 Redis 作为缓存技术)

1. Spring Cache 介绍

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

Spring Cache 提供了一层抽象,底层可以切换不同的 cache 实现。具体就是通过 CacheManager 接口来统一不同的缓存技术。

CacheManger 是 Spring 提供的各种缓存技术抽象接口,针对不同的缓存技术需要实现不同的 CacheManager:

  • CacheManager 接口默认自带的缓存管理器(都存在于 spring-context 包中):[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-7ObFdzQi-1665250913751)(C:/Users/bbbbbge/Pictures/接单/1665152888171.png)]

  • 使用其它缓存技术作为缓存管理器

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

CacheManager 默认的缓存实现为 ConcurrentMapCacheManager ,通过它实现缓存底层是基于 ConcurrentMap 这个数据结构。但要注意的是,这个 map 是基于内存的,当服务重启之后,缓存的数据就没有了。

ConcurrentMap 是一个接口,是一个能够支持并发访问的 java.util.map 集合

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mMpMo0qH-1665250913752)(C:/Users/bbbbbge/Pictures/接单/1665153274575.png)]

2. Spring Cache 常用注解

注解 说明
@EnableCaching 开启缓存注解功能
@Cacheable 在方法执行前 Spring 先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中
@CachePut 将方法的返回值放到缓存中
@CacheEvict 将一条或多条数据从缓存中删除
  • 在 spring boot 项目中,使用缓存技术只需在项目中导入相关缓存技术的依赖包,并在启动类上使用 @EnableCaching 开启缓存技术即可。

  • spring cache 最基础的 api 是存放在 spring-context 包中,而 spring-context 又包含在 spring-boot-starter-web 包中。因此如果只使用 spring cache 最基础的自带的缓存功能,导入 web 包就行了。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-F3tmgTlZ-1665250913753)(C:/Users/bbbbbge/Pictures/接单/1665151585152.png)]

  • 如果要使用 Redis 等技术作为缓存,则需要再导入 spring-boot-starter-cache 和相关缓存技术的依赖。

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    
  • 导入 spring-boot-starter-cache 以来后,CacheManager 就会增多几种。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GrY3C1Db-1665250913754)(C:/Users/bbbbbge/Pictures/接单/1665249344512.png)]

  • 导入 spring-boot-starter-data-redis Redis 的依赖以后,CacheManager 就会增加 RedisCacheManager 实现类。[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RHVbHwMP-1665250913754)(C:/Users/bbbbbge/Pictures/接单/1665249507594.png)]

  • @Cacheable 注解能够将方法的返回值放到缓存中,但要注意返回值对象需要实现 Serializable 序列化接口。

3. Spring Cache 使用方式

3.1 @EnableCaching

使用 @EnableCaching 注解能够开启缓存注解功能。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-v4gQIVMT-1665250913755)(C:/Users/bbbbbge/Pictures/接单/1665222123499.png)]

3.2 @CachePut

使用 @CachePut 注解就能够将方法的返回值放到缓存中,使用该注解时可以指定以下几个参数:

参数 解释 example
value 缓存的名称,每个缓存名称下可以有多个 key,必须指定至少一个 @CachePut(value=“my cache”)
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,默认按照方法的所有参数进行组合 @CachePut(value=“testcache”, key=“#user.id”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 @CachePut(value=“testcache”, condition=“#userName.length()>2”)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AFpv5BiD-1665250913755)(C:/Users/bbbbbge/Pictures/接单/1665220788659.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EiBE8Q5V-1665250913756)(C:/Users/bbbbbge/Pictures/接单/1665220753878.png)]

3.3 @CacheEvict

使用 @CacheEvict 注解就能够将一条或多条数据从缓存中删除,使用该注解时可以指定以下几个参数:

参数 解释 example
value 缓存的名称,每个缓存名称下可以有多个 key,必须指定至少一个 @CacheEvict(value=“my cache”)
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,默认按照方法的所有参数进行组合 @CacheEvict(value=“testcache”, key=“#id”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 @CacheEvict(value=“testcache”, condition=“#userName.length()>2”)
allEntries 是否清空所有缓存内容,默认为 false,如果指定为 true,则方法调用后将立即清空所有缓存 @CachEvict(value=“testcache”, allEntries=true)
beforeInvocation 是否在方法执行前就清空,默认为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存 @CachEvict(value=“testcache”,beforeInvocation=true)

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-s5jhCc5g-1665250913756)(C:/Users/bbbbbge/Pictures/接单/1665221346566.png)]

3.4 @Cacheable

使用 @Cacheable 注解,在方法执行前 Spring 会先查看缓存中是否有数据,如果有数据,则直接返回缓存数据;若没有数据,调用方法并将方法返回值放到缓存中。使用该注解时可以指定以下几个参数:

参数 解释 example
value 缓存的名称,每个缓存名称下可以有多个 key,必须指定至少一个 例如: @Cacheable(value=“mycache”) @Cacheable(value={“cache1”, “cache2”}
key 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,默认按照方法的所有参数进行组合 @Cacheable(value=“testcache”, key=“#userName”)
condition 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存 @Cacheable(value=“testcache”, condition=“#userName.length()>2”)
unless 与 condition 相反,满足条件的时候则不缓存数据 @Cacheable(value=“testcache”, unless=“#result == null”)

注意,使用 @Cacheable 注解如果获取的数据在数据库中查询不到,缓存也会进行存储。为了防止这样的行为,则可以通过 condition 或者 unless 参数去进行条件设置。

**[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ciLI8OAC-1665250913756)(C:/Users/bbbbbge/Pictures/接单/1665221920771.png)]**

3.5 Spring Cache 提供的相关 SpEL 上下文数据

在 Spring Cache 的注解中可以通过 SpEL 表达式来获取方法的参数或返回值等数据,下表就是 Spring Cache 提供的相关 SpEL 上下文数据:

名称 位置 描述 示例
methodName root对象 当前被调用的方法名 root.methodName
method root对象 当前被调用的方法 root.method.name
target root对象 当前被调用的目标对象 root.target
targetClass root对象 当前被调用的目标对象类 root.targetClass
args root对象 当前被调用的方法的参数列表 root.args[0]
caches root对象 当前方法调用使用的缓存列表(如@Cacheable(value={“cache1”, “cache2”})),则有两个cache root.caches[0].name
argument name 执行上下文 当前被调用的方法的参数,如findById(Long id),我们可以通过 #id 拿到参数 user.id
result 执行上下文 方法执行后的返回值(仅当方法执行之后的判断有效,如 ‘unless’,‘@CacheEvict’ 的 beforeInvocation=false,‘condition’ 无法使用) result

4. Spring Cache 使用 Redis 缓存技术

  1. 导包

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-cache</artifactId>
    </dependency>
    
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    
  2. 配置 application.yaml 文件

    spring:
      redis:
        host: 127.0.0.1
        port: 6379
        password: 1234
        database: 0
      cache:
        redis:
          time-to-live: 1800000 # 设置缓存有效期(毫秒)
    
  3. 在启动类上加上 EnableCaching 注解,开启缓存注解功能

    @SpringBootApplication
    @EnableCaching
    public class CacheDemoApplication {
          
          
        public static void main(String[] args) {
          
          
            SpringApplication.run(CacheDemoApplication.class,args);
        }
    }
    
  4. 在 Controller 方法上加入 @Cacheable、@CacheEvict 等注解,进行缓存操作

猜你喜欢

转载自blog.csdn.net/weixin_51367845/article/details/127219282