前言

SpringBoot Cache 是一个很好的缓存框架,可以兼容多种缓存实现,数据量较大的情况下,Redis 应该是最多被使用的。

本文重点介绍 SpringBoot 和 Redis 整合使用的关键流程,并对其中的核心要点给出说明,且附上相应的官方文档链接便于参考。

添加 Maven 依赖

在项目 pom.xml 中添加如下配置:

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
<version>${spring-boot.version}</version>
</dependency>

启用缓存

在项目 启动类 中添加如下注解:

@EnableCaching

配置缓存

配置 Redis 连接信息

Redis 连接信息包括地址、端口、超时时间(秒)和连接池等,可以根据需要选取若干配置即可。

在项目 application.yml 中添加如下配置:

spring:
redis:
host: ${host}
port: ${port}
timeout: 3000
lettuce:
pool:
enabled: true
max-active: 30

SpringBoot 默认使用的 Redis 客户端是 lettuce,不是 Jedis。如果需要使用连接池的话,还需要额外添加一个 Maven 依赖:

<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>${commons-pool2.version}</version>
</dependency>

Redis 连接配置属性参考,注意属性前缀为 spring.redis.*。

配置缓存信息

SpringBoot 支持多个不同名称的缓存,缓存名称需要预先配置,还可以指定缓存的过期时间。对于 Redis 而言,某个名称的缓存实际上就是 Redis 中一个或多个以该名称为前缀的 Key,缓存的过期时间指的就是这部分 Key 的过期时间。

在项目 application.yml 中添加如下配置:

spring:
cache:
cache-names: "cache1,cache2"
redis:
time-to-live: "10m"

缓存配置属性参考,注意属性前缀为 spring.cache.redis.*。

默认情况下,所有缓存的过期时间都是一样的。如果需要对不同的缓存设置不同的过期时间,可以自己扩展实现,参考官方示例

使用缓存

@Cacheable

SpringBoot Cache 可以帮助我们自动缓存某个方法的结果(返回值),使用时我们只需要在方法上面添加注解 @Cacheable,并且指定缓存名称即可:

@Cacheable(cacheNames = {"cos::url"})
public String generatePresignedUrl(String name) {
return ...;
}

缓存名称为 cos::url,调用方法 generatePresignedUrl 时,SpringBoot Cache 会自动检查 Redis 中是否已经缓存过该方法的结果,如果已经缓存过,则直接使用缓存中的结果返回,该方法不会执行;如果没有缓存过,会执行该方法获取结果,缓存结果之后再返回给调用者。

Caching

Key Generation

Redis 检查或缓存结果时均需要一个 Key,SpringBoot Cache 使用 缓存名称(CacheName,如:cos::url)和 参数值(ParameterValue,如:value1)生成 Key,规则如下:

  • 如果方法没有参数,Key 为 CacheName::SimpleKey [],即:cos::url::SimpleKey [];
  • 如果方法只有一个参数,Key 为 CacheName::ParameterValue,即:cos::url::value1;
  • 如果方法有两个或两个以上的参数,Key 为 CacheName::SimpleKey [ParameterValue1,ParameterValue2,...],即:cos::url::SimpleKey [value1,value2];

Default Key Generation

sync

sync 是注解 @Cacheable 的一个属性,值可以是 true 或 false:

如果 sync = false(默认),多线程环境下调用方法 generatePresignedUrl 时,Redis 没有缓存结果的情况下,方法可能会被执行多次;

如果 sync = true,Redis 没有缓存结果的情况下,方法 generatePresignedUrl 只会被执行一次。

Conditional Caching

condition

condition 是注解 @Cacheable 的一个属性,它的值是一个 SpEL 表达式,表达式的计算结果可以是 true 或 false:

如果表达式的计算结果是 true,表示缓存方法结果;

如果表达式的计算结果是 false,表示不缓存方法结果;

Conditional Caching

SpEL 表达式可以使用方法的参数值,也可以调用该方法所在 Bean 的其它方法,如:

#name.length() < 32

方法参数 name 的参数值长度小于 32 时,方法结果才会被缓存;

condition = "#root.target.check(#name)"

check() 必须是公开的(public),且返回值必须是布尔类型(Boolean);只有 check() 返回值为 true 时,方法结果才会被缓存。

Available Caching SpEL Evaluation Context

使用限制

如果方法 generatePresignedUrl 被位于一个 Bean 的其它方法调用时,缓存不会生效;也就是说,方法 generatePresignedUrl 必须被其它 Bean 的方法调用时,缓存才会生效。原因主要是和 Spring 的代理机制有关,详情可以参考:Spring Cache @Cacheable - not working while calling from another method of the same bean

SpringBoot Cache 还支持其它注解,可以参考 Declarative Annotation-based Caching

RedisTemplate

如果我们需要自己实现缓存逻辑,SpringBoot Cache 提供了一个封装 Redis 常用操作的工具模板类:RedisTemplate,并且会创建好它的实例,使用时直接注入即可:

@Autowired
private StringRedisTemplate template; @Autowired
private RedisTemplate<String, String> template2; @Autowired
private RedisTemplate<String, Integer> template3;

RedisTemplate 支持泛型,我们可以根据自己的需求注入一个或多个实例;如果键值的类型都是 String,可以直接使用 StringRedisTemplate

结语

SpringBoot 整合 Redis 使用时,如果仅仅是需要读取或缓存数据,直接使用注解的方式相较于使用 RedisTemplate 的方式,可以避免大量的缓存冗余代码,更多地关注业务逻辑;但是缺点也比较明显,操控性比较差。实际使用时,可以灵活结合两者,优先使用注解方式;注解方式受限时,再结合 RedisTemplate 作为补充。

SpringBoot Redis 实践指南的更多相关文章

  1. Disconf实践指南:使用篇

    在上一篇文章Disconf实践指南:安装篇介绍了如何在本地搭建Disconf环境,下面我们介绍如何在项目中使用Disconf.由于某些功能特性对源码做了修改,所以在官方文档并没有提及. 环境基于mac ...

  2. Celery的实践指南

    http://www.cnblogs.com/ToDoToTry/p/5453149.html Celery的实践指南   Celery的实践指南 celery原理: celery实际上是实现了一个典 ...

  3. Disconf实践指南:改造篇

    上一篇文章Disconf实践指南:使用篇介绍了如何在项目中应用disconf,虽然实现了分布式配置的实时刷新,但是我们希望能够去除所有的配置文件,把配置都交给disconf管理,本地只需要实现配置监听 ...

  4. Disconf实践指南:安装篇

    Disconf是百度开源出来的一款基于Zookeeper的分布式配置管理软件.目前很多公司都在使用,包括滴滴.百度.网易.顺丰等公司.通过简单的界面操作就可以动态修改配置属性,还是很方便的.使用Dis ...

  5. redis入门指南(二)—— 数据操作相关命令

    写在前面 以下绝大部分内容取材于<redis入门指南>,部分结合个人知识,实践后得出. 只记录重要,明确,属于新知的相关内容,杜绝冗余和重复. 字符串 1.字符串类型是redis中最常见的 ...

  6. redis入门指南(三)—— 事务、过期时间、SORT命令、消息通知与管道

    写在前面 学习<redis入门指南>笔记,结合实践,只记录重要,明确,属于新知的相关内容. 事务 1.redis中的事务由一组命令的集合组成,要么都执行,要么都不执行,同时redis的事务 ...

  7. redis入门指南(四)—— redis如何节省空间

    写在前面 学习<redis入门指南>笔记,结合实践,只记录重要,明确,属于新知的相关内容. 节省空间 1.redis对于它所支持的五种数据类型,每种都提供了两种及以上的编码方式去存储(具体 ...

  8. redis入门指南(五)—— 复制与哨兵

    写在前面 学习<redis入门指南>笔记,结合实践,只记录重要,明确,属于新知的相关内容. 一.复制 1.在复制中,数据库分为两类,一类主数据库,一类从数据库,主库用来读写,从库用来读,主 ...

  9. redis入门指南(六)—— 集群

    写在前面 学习<redis入门指南>笔记,结合实践,只记录重要,明确,属于新知的相关内容. 配置集群 1.配置集群,集群解决了单点故障以及单台机器内存上限的问题,使用集群时,只需要将配置文 ...

随机推荐

  1. C语言泛型编程——泛型冒泡排序

    在实际编程中,常常会需要一些方法(函数),比如排序,它们具体实现基本一致,仅仅只有参数类型不同, 那么可不可以有一种通用的函数,不管是什么类型的参数都可以通用呢? 泛型编程:泛型即是指具有在多种数据类 ...

  2. 移动端比1px还小的border

    巧用border 在移动端 经常出现border,细边框但有的时候 产品大大1px甚至乎会觉得不够细那么要如何写出比1px还要小的border下面是代码 希望对大家有所帮助 .thinner-bord ...

  3. Vue.js快速介绍-超级马里奥像素艺术

    原文出处:Quick Introduction to Vue.js - Super Mario Pixel Art ::代码我已经归纳在github上:[vue2-pixel-art]::::__查看 ...

  4. 关于recyclerview其item数据重复问题

    查找方法(query)的list只定义对象,不实例化,等到要添加的时候,再new一个新的对象出来. 千万不要如下图这样,否则item显示出来的永远是最新数据. (这个bug找了两天,还是基本功不扎实, ...

  5. idea 启动微服务 设置 run dashboard

    微服务如果很多,启动时如果在run窗口,会不是很方便,所以idea中配置了rundashboard,有时不自动出现时,需要进行配置: 配置操作如下: 我的idea版本2020.2 1.在父工程的.id ...

  6. 为什么局部内部类访问外边的局部变量必须为final

    6.局部内部类访问外边的局部变量时,此变量必须为final类型 马克-to-win:由于技术方面的限制,java的设计者们做出如下语法规定:局部内部类访问外边的局部变量时,此变量必须为final类型, ...

  7. git-flow-avh的使用过程

    安装: 在mac上 brew install git-flow-avh 使用: 在仓库中 git flow init 一路回车就行,这个命令相当于写入一些默认命令流程到.git中, 此命令执行之后会增 ...

  8. Spring4Shell的漏洞原理分析

    Spring框架最新的PoC 这两天出来的一个RCE漏洞,但是有以下的条件限制才行: 必须是jdk9及以上 必须是部署在tomcat的应用 是springmvc的或者webflux的应用 具体的可以查 ...

  9. 如何在 Java 中实现无向图

    基本概念 图的定义 一个图是由点集 \(V=\{v_i\}\) 和 \(V\) 中元素的无序对的一个集合 \(E=\{e_k\}\) 所构成的二元组,记为 \(G=(V,E)\),\(V\) 中的元素 ...

  10. golang 中 sync.Mutex 的实现

    mutex 的实现思想 mutex 主要有两个 method: Lock() 和 Unlock() Lock() 可以通过一个 CAS 操作来实现 func (m *Mutex) Lock() { f ...