使用Spring Cache集成Redis
SpringBoot是为了简化Spring应用的创建、运行、调试、部署等一系列问题而诞生的产物,自动装配的特性让我们可以更好的关注业务本身而不是外部的XML配置,我们只需遵循规范,引入相关的依赖就可以轻易的搭建出一个 WEB 工程
Spring 3.1 引入了激动人心的基于注释(annotation)的缓存(cache)技术,它本质上不是一个具体的缓存实现方案(例如 EHCache 或者 Redis),而是一个对缓存使用的抽象,通过在既有代码中添加少量它定义的各种 annotation,即能够达到缓存方法的返回对象的效果。
特点
具备相当的好的灵活性,不仅能够使用 SpEL(Spring Expression Language)来定义缓存的 key 和各种 condition,还提供开箱即用的缓存临时存储方案,也支持和主流的专业缓存例如 EHCache、Redis、Guava 的集成。
- 基于
annotation即可使得现有代码支持缓存 - 开箱即用
Out-Of-The-Box,不用安装和部署额外第三方组件即可使用缓存 - 支持
Spring Express Language,能使用对象的任何属性或者方法来定义缓存的key和condition - 支持
AspectJ,并通过其实现任何方法的缓存支持 - 支持自定义
key和自定义缓存管理者,具有相当的灵活性和扩展性
使用前后
下面针对Spring Cache使用前后给出了伪代码部分,具体中也许比这要更加复杂,但是Spring Cache都可以很好的应对
使用前
我们需要硬编码,如果切换Cache Client还需要修改代码,耦合度高,不易于维护
1 |
public String get(String key) {
|
使用后
基于Spring Cache注解,缓存由开发者自己配置,但不用参与到具体编码
1 |
@Cacheable(value = "user", key = "#key") |
添加依赖
在 pom.xml 中添加 spring-boot-starter-data-redis的依赖
1 |
<dependency> |
属性配置
在 application.properties 文件中配置如下内容,由于Spring Boot2.x 的改动,连接池相关配置需要通过spring.redis.lettuce.pool或者 spring.redis.jedis.pool 进行配置了。使用了Spring Cache后,能指定spring.cache.type就手动指定一下,虽然它会自动去适配已有Cache的依赖,但先后顺序会对Redis使用有影响(JCache -> EhCache -> Redis -> Guava)
1 |
spring.redis.host=localhost |
具体编码
实体类
创建一个User类,目的是为了模拟对象存储
1 |
package com.battcn.entity; import java.io.Serializable; /** |
定义接口
1 |
package com.battcn.service; import com.battcn.entity.User; /** |
###实现类
为了方便演示数据库操作,直接定义了一个Map<Long, User> DATABASES,这里的核心就是@Cacheable、@CachePut、@CacheEvict 三个注解
1 |
package com.battcn.service.impl; import com.battcn.entity.User; |
主函数
@EnableCaching 必须要加,否则spring-data-cache相关注解不会生效…
1 |
package com.battcn; import org.springframework.boot.SpringApplication; |
测试
完成准备事项后,编写一个junit测试类来检验代码的正确性,有很多人质疑过Redis线程安全性,故下面也提供了响应的测试案例,如有疑问欢迎指正
1 |
package com.battcn; import com.battcn.entity.User; |
启动测试类,结果和我们期望的一致,可以看到增删改查中,查询是没有日志输出的,因为它直接从缓存中获取的数据,而添加、修改、删除都是会进入方法内执行具体的业务代码,然后通过切面去删除掉Redis中的缓存数据。其中 # 号代表这是一个 SpEL 表达式,此表达式可以遍历方法的参数对象,具体语法可以参考 Spring 的相关文档手册。
1 |
2018-05-14 09:20:55.303 INFO 21176 --- [ main] com.battcn.service.impl.UserServiceImpl : 进入 saveOrUpdate 方法 |
其它类型
下列的就是Redis其它类型所对应的操作方式
- opsForValue: 对应 String(字符串)
- opsForZSet: 对应 ZSet(有序集合)
- opsForHash: 对应 Hash(哈希)
- opsForList: 对应 List(列表)
- opsForSet: 对应 Set(集合)
- opsForGeo: 对应 GEO(地理位置)
根据条件操作缓存
根据条件操作缓存内容并不影响数据库操作,条件表达式返回一个布尔值,true/false,当条件为true,则进行缓存操作,否则直接调用方法执行的返回结果。
长度:@CachePut(value = "user", key = "#user.id",condition = "#user.username.length() < 10")只缓存用户名长度少于10的数据大小:@Cacheable(value = "user", key = "#id",condition = "#id < 10")只缓存ID小于10的数据组合:@Cacheable(value="user",key="#user.username.concat(##user.password)")提前操作:@CacheEvict(value="user",allEntries=true,beforeInvocation=true)加上beforeInvocation=true后,不管内部是否报错,缓存都将被清除,默认情况为false
注解介绍
@Cacheable(根据方法的请求参数对其结果进行缓存)
- key: 缓存的 key,可以为空,如果指定要按照 SpEL 表达式编写,如果不指定,则缺省按照方法的所有参数进行组合(如:
@Cacheable(value="user",key="#userName")) - value: 缓存的名称,必须指定至少一个(如:
@Cacheable(value="user")或者@Cacheable(value={"user1","use2"})) - condition: 缓存的条件,可以为空,使用 SpEL 编写,返回 true 或者 false,只有为 true 才进行缓存(如:
@Cacheable(value = "user", key = "#id",condition = "#id < 10"))
@CachePut(根据方法的请求参数对其结果进行缓存,和
@Cacheable不同的是,它每次都会触发真实方法的调用)
- key: 同上
- value: 同上
- condition: 同上
@CachEvict(根据条件对缓存进行清空)
- key: 同上
- value: 同上
- condition: 同上
- allEntries: 是否清空所有缓存内容,缺省为 false,如果指定为 true,则方法调用后将立即清空所有缓存(如:
@CacheEvict(value = "user", key = "#id", allEntries = true)) - beforeInvocation: 是否在方法执行前就清空,缺省为 false,如果指定为 true,则在方法还没有执行的时候就清空缓存,缺省情况下,如果方法执行抛出异常,则不会清空缓存(如:
@CacheEvict(value = "user", key = "#id", beforeInvocation = true))
总结
spring-cache文档: https://docs.spring.io/spring/docs/5.0.5.RELEASE/spring-framework-reference/integration.html#cache-introductionspring-data-redis文档: https://docs.spring.io/spring-data/redis/docs/2.0.1.RELEASE/reference/html/#new-in-2.0.0Redis 文档: https://redis.io/documentationRedis 中文文档: http://www.redis.cn/commands.html
使用Spring Cache集成Redis的更多相关文章
- Spring Boot (24) 使用Spring Cache集成Redis
Spring 3.1引入了基于注解(annotation)的缓存(cache)技术,它本质不是一个具体的缓存实现方案,而是一个对缓存使用的抽象,通过在既有代码中添加少量它定义的个助攻annotatio ...
- Spring Boot(八)集成Spring Cache 和 Redis
在Spring Boot中添加spring-boot-starter-data-redis依赖: <dependency> <groupId>org.springframewo ...
- springboot整合spring @Cache和Redis
转载请注明出处:https://www.cnblogs.com/wenjunwei/p/10779450.html spring基于注解的缓存 对于缓存声明,spring的缓存提供了一组java注解: ...
- Spring+Dubbo集成Redis的两种解决方案
当下我们的系统数据库压力都非常大,解决数据库的瓶颈问题势在必行,为了解决数据库的压力等需求,我们常用的是各种缓存,比如redis,本文就来简单讲解一下如何集成redis缓存存储,附github源码. ...
- (35)Spring Boot集成Redis实现缓存机制【从零开始学Spring Boot】
[本文章是否对你有用以及是否有好的建议,请留言] 本文章牵涉到的技术点比较多:Spring Data JPA.Redis.Spring MVC,Spirng Cache,所以在看这篇文章的时候,需要对 ...
- 【Spring】17、spring cache 与redis缓存整合
spring cache,基本能够满足一般应用对缓存的需求,但现实总是很复杂,当你的用户量上去或者性能跟不上,总需要进行扩展,这个时候你或许对其提供的内存缓存不满意了,因为其不支持高可用性,也不具备持 ...
- Spring Boot 2.X(六):Spring Boot 集成Redis
Redis 简介 什么是 Redis Redis 是目前使用的非常广泛的免费开源内存数据库,是一个高性能的 key-value 数据库. Redis 与其他 key-value 缓存(如 Memcac ...
- SpringBoot(十一): Spring Boot集成Redis
1.在 pom.xml 中配置相关的 jar 依赖: <!-- 加载 spring boot redis 包 --> <dependency> <groupId>o ...
- spring boot集成redis基础入门
redis 支持持久化数据,不仅支持key-value类型的数据,还拥有list,set,zset,hash等数据结构的存储. 可以进行master-slave模式的数据备份 更多redis相关文档请 ...
随机推荐
- Java实现 LeetCode 350 两个数组的交集 II(二)
350. 两个数组的交集 II 给定两个数组,编写一个函数来计算它们的交集. 示例 1: 输入: nums1 = [1,2,2,1], nums2 = [2,2] 输出: [2,2] 示例 2: 输入 ...
- Java实现奇偶数排序
1 问题描述 给定一个整数数组,请调整 数组中数的顺序,使得所有奇数位于数组的前半部分,所有偶数位于数组的后半部分.要求时间复杂度为O(n). 2 解决方案 2.1 一头一尾指针往中间扫描法 pack ...
- java实现平面4点最小距离
已知平面上若干个点的坐标. 需要求出在所有的组合中,4个点间平均距离的最小值(四舍五入,保留2位小数). 比如有4个点:a,b,c,d, 则平均距离是指:ab, ac, ad, bc, bd, cd ...
- python—socket编程
一:客户端/服务器 架构 1.硬件C/S架构:(例如,打印机) 2.软件C/S架构:互联网中处处是C/S架构 腾讯作为服务端为你提供视频,你得下个腾讯视频客户端才能看它的视频 C/S架构与socket ...
- Node第三方模块
node第三方模块集合 1.nrm 切换npm下载的镜像地址 nrm ls 查看可用镜像 nrm use +镜像名 2.nodemon 在控制台nodenom替代node命令执行nodejs文件, ...
- 浅谈Unity的脚本执行顺序
一.添加脚本的顺序 这是一张官方的脚本顺序图 一般,当我们把脚本绑定在游戏对象上时,或者点击绑定好的脚本的reset按钮时,会调用Reset() 当我们初始化一个对象时,会先调用Awake()在调用O ...
- 关于cronExpression表达式
spring 定时任务设置,关于cronExpression表达式: 字段 允许值 允许的特殊字符 秒 0-59 , - * / 分 0-59 , - * / 小时 0-23 , - * / 日期 1 ...
- Django 源码阅读笔记(基础视图)
django源码解读之 View View. ContextMixin.TemplateResponseMixin.TemplateView.RedirectView View class View( ...
- Asp.Net Core入门之自定义中间件
什么是中间件? 这里引用官方解释: 中间件是用于组成应用程序管道来处理请求和响应的组件.管道内的每一个组件都可以选择是否将请求交给下一个组件.并在管道中调用下一个组件之前和之后执行某些操作.请求委托被 ...
- cb39a_c++_STL_算法_for_each_transform_比较
cb39a_c++_STL_算法_for_each_transform_比较for_each() 速度快,不灵活transform() 速度慢, 非常灵活 STL算法-修改性算法for_each()c ...