首页 > 数据库 >SpringBoot使用注解方式集成Redis缓存

SpringBoot使用注解方式集成Redis缓存

时间:2022-12-03 23:32:01浏览次数:64  
标签:缓存 SpringBoot Redis 指定 Cacheable key 注解 方法


SpringBoot中Redis缓存注解

Spring框架中所有的注解都是通过AOP的原理实现的,即Spring框架为我们创建代理对象,代理对象去实现注解的功能。所以当一个支持缓存的方法,在对象内部被调用的时候,是不会触发缓存功能的,因为当前类方法调用当前类方法使用的是this.调用,也就是当前对象,而不是代理对象,增强没有上生效。

@Cacheable、@Cacheput、@CacheEvict 是 Spring3.1 版本以后对缓存支持的注解。这些注解作用在方法上。使用了Spring AOP的思想。@Cacheable、@Cacheput、@CacheEvict 这些注解不是专门针对 Redis 的,而是针对本地缓存的。但是在 SpringBoot 框架中,可以使用这些注解配合 Redis 进行使用。

@Cacheable

使用存在查询的方法上

此注解标记可以使用在一个方法上也可以使用在一个类上。标记在方法上表示该方法是支持缓存的,标记在类上表示该类中所有的方法都是支持缓存的。

该注解的作用原理: 首先在执行查询方法之前,会先查询缓存,如果在缓存中查询到想要的数据就会直接返回,不会再执行此方法;如果在缓存中没有查到就会查询数据库,并且将查询结果作为该方法的返回值返回。Spring Cache会将该方法的返回值缓存起来。保证下次利用同样的参数执行该方法的时候,直接从缓存中获取结果,而不需要执行此方法。

在缓存方法的返回值的时候,是以键值对的形式存储到缓存中。值就是该方法的返回结果。键需要自己指定,spring中支持两种生成key的策略。EL表达式和自定义。在EL表达式中详细说明。

运行流程

  • 方法运行之前,先去查询Cache(缓存组件),按照cacheNames指定的名字获取(CacheManager先获取相应的缓存),第一次获取缓存如果没有Cache组件会自动创建。
  • 去Cache中查找缓存的内容,使用一个key,默认就是方法的参数,key是按照某种策略生成的,默认是使用keyGenerator生成的,默认使用SimpleKeyGenerator生成key。
  • SimpleKeyGenerator生成key的默认策略:
  • 如果没有参数;key=new SimpleKey();
  • 如果有一个参数:key=参数的值
  • 如果有多个参数:key=new SimpleKey(params);
  • 没有查到缓存就调用目标方法。
  • 将目标方法返回的结果,放进缓存中。 @Cacheable标注的方法执行之前先来检查缓存中有没有这个数据,默认按照参数的值作为key去查询缓存,如果没有就运行方法并将结果放入缓存;以后再来调用就可以直接使用缓存中的数据。

@Cacheable注解中可以定义三个属性@Cacheable(value="",key="",condition="",unless="")

  • cacheNames/value: 指定缓存的名称,该属性必须指定。表示当前方法的返回值会被存储到哪个缓存上。也可以指定多个。
  • key: 指定缓存结果对应的key。支持SpEL表达式的方式赋值。可以不指定,不指定的时候使用默认值,默认值就是将方法的所有参数进行组合,作为key。

Spring还提供了root对象来生成key,通过root对象可以获取到一下信息:

属性名称

描述

示例

methodName

当前方法名

#root.methodName

method

当前方法

#root.method.name

target

当前被调用对象

#root.target

targetClass

当前被调用对象的class

#root.targetClass

args

当前方法参数组成的数组

#root.args[0]

caches

当前被调用的方法使用的Cache

#root.caches[0].name

  • keyGenerator: key的生成器,可以自己指定key的生成器的组件id。 默认生成器: SimpleKeyGenerator
  • key 和 keyGenerator 属性两者互斥,二选一使用
  • cacheManager: 指定缓存管理器,或者 cacheResolver 指定获取解析器
  • condition: 表示缓存条件,不设置的时候,缓存所有的返回结果。设置的时候,通过SpEL表达式指定,只有当表达式为true的时候,缓存才会被触发,将返回结果缓存。
  • 例如: condition = "#a0>1"表示第一个参数的值>1的时候才进行缓存
@Cacheable(cacheNames = "sum", key = "#root.args[0]", condition = "#id!=null", unless = "#result==null")
public Map<String, ResData> selectSum(Long id) {
// 查询,并将结果返回
return sumDao.querySum(id);
}
  • unless: 除…之外。也表示缓存条件,不设置的时候,缓存所有的返回结果。设置的时候,通过SpEL表达式指定,只有当表达式为false的时候,缓存才会被触发,将返回结果缓存。
@Cacheable(cacheNames = "sum", key = "#root.args[0]", condition = "#id!=null", unless = "#result==null")
public Map<String, ResData> selectSum(Long id) {
// 查询,并将结果返回
return sumDao.querySum(id);
}

​注意:condition & unless 区别:​​ condition用方法的参数作为判断条件,也就是说根据犯法的参数判断是否信息存放到缓存中。而unless是将方法的返回值作为判断条件,也就是说根据方法的返回值判断,是否将信息存放到缓存中。

  • sync: 是否使用异步模式

 

@Cacheput

使用在添加和修改的方法上

@Cacheput 标注的方法​​在执行之前不会去查询缓存​​​,每次都会执行该方法,在该方法执行完后,将该方法的返回值以键值对的形式保存到缓存中。​​和 @Cacheable 不同的是,它每次都会触发真实方法的调用​

其属性和@Cacheable属性一样。

value属性,必须指定。

 

@CacheEvict

用在清除缓存到方法上。

可以标记在类上,也可以标记在方法上,标记在雷伤的时候表示该类中所有的方法执行都会触发清除缓存的操作

该注解可以定义的属性有:value、key、condition、allEntries 和 beforeInvocation。

  • value: 指定缓存的名称
  • key: 指定要清除的缓存的key。不指定将会使用默认生成策略生成的key,默认生成策略就是将方法中所有参数拼接为key
  • condition: 指定触发清除缓存操作的条件。
  • allEntries: 该属性是一个boolean类型的,表示是否清除缓存中的所有的数据。默认的是false,当指定为true的时候,将会忽略指定的key。会清除缓存中所有的数据。
  • beforeInvocation: 清除操作默认是在对应方法成功执行之后触发的,即方法如果因为抛出异常而未能成功返回时也不会触发清除操作。使用beforeInvocation可以改变触发清除操作的时间,当我们指定该属性值为true时,Spring会在调用该方法之前清除缓存中的指定元素。

 

@CacheConfig

标记在类上。有时候一个类中可能会有多个缓存操作,而这些缓存使用的可能是同一个缓存,这个时候就可以使用@CacheConfig来配置缓存的名称。

所有的@Cacheable()里面都有一个value=“xxx”的属性,这显然如果方法多了,写起来也是挺累的,如果可以一次性声明完 那就省事了, 所以,有了@CacheConfig这个配置。如果你在你的方法写别的名字,那么依然以方法的名字为准。

 

@EnableCaching

springboot启动器上添加此注解,表示开始缓存功能,否则缓存不生效

 

参考网址


标签:缓存,SpringBoot,Redis,指定,Cacheable,key,注解,方法
From: https://blog.51cto.com/u_15891990/5908831

相关文章

  • SpringBoot整合Mybatis多数据源
    Mybatis中如何配置多数据源一什么情况下会用到多数据库?场景1:一个商城网站,一个游戏网站,商城网站已经做好,游戏网站正在开发,游戏网站上的很多道具需要用到商城网站的产品数据,......
  • SpringBoot整合Mybatis多数据源
    Mybatis中如何配置多数据源一什么情况下会用到多数据库?场景1:一个商城网站,一个游戏网站,商城网站已经做好,游戏网站正在开发,游戏网站上的很多道具需要用到商城网站......
  • Redis配置、优化以及相命令
    一、关系数据库和非关系型数据库1、关系型数据库关系型数据库是一个结构化的数据库,创建在关系模型(二维表格模型)基础上,一般面向于记录。SQL语句(标准数据查询语言)就是一种......
  • Redis 命令
    查看所有键(生产环境避免使用)keys*键总数(直接获取Redis内置的键总数变量,所以dbsize命令的时间复杂度是O(1))dbsize检查键是否存在(存在则返回1,不存在为0)ex......
  • SpringCloud+MyBatis+Redis整合—— 超详细实例(一)
    1、SpringCloud+MyBatisMyBatis是一款优秀的轻量级半自动持久层框架,与之相对应的还有hibernate框架。①  话不多说,接下来搭建SpringCloud+MyBatis环境:第一步......
  • SpringCloud+MyBatis+Redis整合—— 超详细实例
    SpringCloud+MyBatis+Redisredis①是一种nosql数据库,以键值对<key,value>的形式存储数据,其速度相比于MySQL之类的数据库,相当于内存读写与硬盘读写的差别,所以常常用作缓存,用......
  • redis缓存
    redis缓存1、为什么使用redis2、使用redis有什么缺点3、单线程的redis为什么这么快4、redis的数据类型,以及每种数据类型的使用场景5、redis的过期策略以及内存淘汰......
  • TP5使用Redis处理电商秒杀-靳宇灵
    TP5使用Redis处理电商秒杀1、首先在TP5中创建抢购活动所需要的Redis类库文件,代码如下:<phpnamespaceapp\base\service;usemikkle\tp_redis\RedisHashInfoBase;......
  • Android 内存缓存框架 LruCache 的实现原理,手写试试?
    本文已收录到AndroidFamily,技术和职场问题,请关注公众号[彭旭锐]提问。前言大家好,我是小彭。在之前的文章里,我们聊到了LRU缓存淘汰算法,并且分析Java标准库中支......
  • Redis面试问题
    问题一:Redis到底是单线程还是多线程?Redis6.0版本之前的单线程指的是其网络/O和键值对读写是由一个线程完成的Redis6.0引入的多线程指的是网络请求过程采用了多线程,而键值......