一、介绍

spring cache 是spring3版本之后引入的一项技术,可以简化对于缓存层的操作,spring cache与springcloud stream类似,都是基于抽象层,可以任意切换其实现。其核心是CacheManagerCache这两个接口,所有由spring整合的cache都要实现这两个接口、Redis的实现类则是 RedisCacheRedisManager。

二、使用

Ⅰ、查询

需要导入的依赖

 <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>

   编写对于cache的配置

 @EnableCaching
@SpringBootConfiguration
public class CacheConfig { @Autowired
private RedisConnectionFactory connectionFactory; @Bean // 如果有多个CacheManager的话需要使用@Primary直接指定那个是默认的
public RedisCacheManager cacheManager() {
RedisSerializer<String> redisSerializer = new StringRedisSerializer();
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class); ObjectMapper om = new ObjectMapper();
// 防止在序列化的过程中丢失对象的属性
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
// 开启实体类和json的类型转换
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om); // 配置序列化(解决乱码的问题)
RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig() .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer)) .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
// 不缓存空值
.disableCachingNullValues()
// 1分钟过期
.entryTtl(Duration.ofMinutes(1))
;
RedisCacheManager cacheManager = RedisCacheManager.builder(connectionFactory)
.cacheDefaults(config)
.build();
return cacheManager;
}
}

进行以上配置即可使用springboot cache了,还有一个key的生成策略的配置(可选)

 @Bean
public KeyGenerator keyGenerator() {
return (target, method, params) -> {
StringBuffer key = new StringBuffer();
key.append(target.getClass().getSimpleName() + "#" + method.getName() + "(");
for (Object args : params) {
key.append(args + ",");
}
key.deleteCharAt(key.length() - 1);
key.append(")");
return key.toString();
};
}

注意:如果配置了KeyGenerator ,在进行缓存的时候如果不指定key的话,最后会把生成的key缓存起来,如果同时配置了KeyGenerator 和key则优先使用key。

在controller或者service的类上面添加 @CacheConfig ,注解里面的参数详情见下表:

参数名 参数值 作用
cacheNames 可以随意填写,一般是一个模块或者一个很重要的功能名称 无具体作用,只是用来区分缓存,方便管理
keyGenerator 就是自己配置的KeyGenerator的名称 全局key都会以他的策略去生成
cacheManager 自己配置的CacheManager 用来操作Cache对象的,很多对于缓存的配置也由他去管理

在标有@CacheConfig的类里面编写一个查询单个对象的方法并添加 @Cacheable注解

 @Cacheable(key = "#id", unless = "#result == null")
@PatchMapping("/course/{id}")
public Course courseInfo(@PathVariable Integer id) {
log.info("进来了 .. ");
return courseService.getCourseInfo(id);
}

执行完该方法后,执行结果将会被缓存到Redis:

@Cacheable注解中参数详情见下表:

参数名 作用
cacheNames  被缓存的时候的命名空间
key 这里的key的优先级是最高的,可以覆盖掉全局配置的key,如果不配置的话使用的就是全局的key
keyGenerator  指定的缓存的key的生成器,默认没有
cacheManager  指定要使用哪个缓存管理器。默认是底层自动配置的管理器
condition 满足什么条件会进行缓存,里面可以写简单的表达式进行逻辑判断
unless 满足什么条件不进行缓存,里面可以写简单的表达式进行逻辑判断
sync 加入缓存的这个操作是否是同步的

Ⅱ、 修改

编写一个修改的方法,参数传对象,返回值也改成这个对象

 @PutMapping("/course")
public Course modifyCoruse(@RequestBody Course course) {
courseService.updateCourse(course);
return course;
}

在方法上面添加 @CachePut(key = "#course.id") 注解,这个注解表示将方法的返回值更新到缓存中,注解中的参数和 @Cacheable 中的一样,这里就略过了。

Ⅲ、 删除

编写删除方法,在方法上添加@CacheEvict 注解

 @CacheEvict(key = "#id")
@DeleteMapping("/course/{id}")
public void removeCourse(@PathVariable Integer id) {
courseService.remove(id);
}

  @CacheEvict 的参数信息见下表:

参数名 描述
allEntries 是否删除该命名空间下面的全部缓存,默认是false
beforeInvocation 在执行删除方法前就执行清空缓存操作,默认是false,如果删除方法执行报错该注解则不执行

三、 基于代码的Cache的使用

因为我们有配置的CacheManager,所以可以利用RedisCacheManager对象去手动操作cache,首先将CacheManager注入进来:

 @Resource
private CacheManager cacheManager; @PatchMapping("/course2/{id}")
public Course course2(@PathVariable Integer id) {
// 获取指定命名空间的cache
Cache cache = cacheManager.getCache("course");
// 通过key获取对应的value
Cache.ValueWrapper wrapper = cache.get(2);
if (wrapper == null) {
// 查询数据库
Course course = courseService.getCourseInfo(id);
// 加入缓存
cache.put(course.getId(), course);
return course;
} else {
// 将缓存的结果返回
// 因为配置了enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
// 所以在进行强转的时候不会报错
return (Course) wrapper.get();
}
}

如果还看不明白,请去码云拉取源码 https://gitee.com/tianmaoliln/Spring-Boot-Cache.git

你想成为什么样的人,就会成为什么样的人!

SpringBoot2.x操作缓存的新姿势的更多相关文章

  1. 【转+自己研究】新姿势之Docker Remote API未授权访问漏洞分析和利用

    0x00 概述 最近提交了一些关于 docker remote api 未授权访问导致代码泄露.获取服务器root权限的漏洞,造成的影响都比较严重,比如 新姿势之获取果壳全站代码和多台机器root权限 ...

  2. Broadcom BCM94352z/DW1560驱动新姿势

    转自:https://blog.daliansky.net/Broadcom-BCM94352z-DW1560-drive-new-posture.html Broadcom WiFi/BlueToo ...

  3. vue组件通信新姿势

    在vue项目实际开发中我们经常会使用props和emit来进行子父组件的传值通信,父组件向子组件传递数据是通过prop传递的, 子组件传递数据给父组件是通过$emit触发事件来做到的.例如: Vue. ...

  4. Java计时新姿势

    为获得更好的阅读体验,请访问原文:传送门 前言: 最近公司来了个大佬,从他那里学到不少东西,其中一个就是计时 的新姿势「StopWatch」,赶紧来一起了解了解吧! 一.最简单的计时 在我们的程序中不 ...

  5. FJNU 1159 Fat Brother’s new way(胖哥的新姿势)

    FJNU 1159 Fat Brother’s new way(胖哥的新姿势) Time Limit: 1000MS   Memory Limit: 257792K [Description] [题目 ...

  6. [Cache] C#操作缓存--CacheHelper缓存帮助类 (转载)

    点击下载 CacheHelper.zip CacheHelper 缓存帮助类 C#怎么操作缓存 怎么设置和取缓存数据,都在这个类里面呢 下面看一下代码吧 /// <summary> /// ...

  7. JSON CSRF新姿势

    以前做渗透测试,遇到过很多次POST数据为JSON数据的CSRF,一直没有搞定,最近发现一个新姿势, ​​​本文作者:Mannix@安全文库 微信公众号:安全文库 测试的时候,当应用程序验证了Cont ...

  8. 转载 Python 操作 MySQL 的正确姿势 - 琉璃块

    Python 操作 MySQL 的正确姿势 收录待用,修改转载已取得腾讯云授权 作者 |邵建永 编辑 | 顾乡 使用Python进行MySQL的库主要有三个,Python-MySQL(更熟悉的名字可能 ...

  9. bzoj1656: [Usaco2006 Jan] The Grove 树木 (bfs+新姿势)

      题目大意:一个n*m的图中,“.”可走,“X”不可走,“*”为起点,问从起点开始绕所有X一圈回到起点最少需要走多少步. 一开始看到这题,自己脑洞了下怎么写,应该是可过,然后跑去看了题解,又学会了一 ...

随机推荐

  1. Java类成员之内部类

    内部类含义: 在Java中允许一个类的定义位于另一个类的内部,前者称为内部类,后者称为外部类. Inner class 一般用在定义它的类或语句块之内,在外部引用它时必须给出完整的名称. Inner ...

  2. CentOS6.8 LAMP

    第一次配置LAMP运行环境,上网查询了很多资料,一边试命令一边学习.服务器重置了很多次. 虽然有OneinStack这个方便的网站一键命令部署,但知道这个网站却是我自己踩坑之后的事情了,故此记录. 1 ...

  3. 理解setTimeout()

    之前在网上看了很多关于setTimeout的文章,但我感觉都只是点到为止,并没有较深入的去剖析,也可能是我脑袋瓜笨,不容易被点解.后面看了<你不知道的javascript-上卷>一书,决定 ...

  4. Linux安装python和更新pip

    一.安装python 1.安装依赖包 1).安装gcc 通过gcc --version 查看,若没有则安装gcc yum -y install gcc 2).安装其他依赖包 yum -y instal ...

  5. 靶机-SickOs 1.2 Walkthrough

    SickOs:1.2 https://www.vulnhub.com/entry/sickos-12,144/ 参考:https://www.cnblogs.com/yuzly/p/10854392. ...

  6. SpringBoot_Web开发_定制错误数据

    SpringBoot默认的错误处理机制 默认效果: ​ 1).浏览器,返回一个默认的错误页面 2).如果是其他客户端,默认响应一个json数据 原理: ​ 可以参照ErrorMvcAutoConfig ...

  7. 异想家纯C语言矩阵运算库

    Sandeepin最近做的项目中需要在嵌入式芯片里跑一些算法,而这些单片机性能不上不下,它能跑些简单的程序,但又还没到上Linux系统的地步.所以只好用C语言写一些在高级语言里一个函数就解决的算法了, ...

  8. sqli_labs学习笔记(一)Less-21~Less-37

    续上,开门见山 Less-21 Cookie Injection- Error Based- complex - string ( 基于错误的复杂的字符型Cookie注入) 登录后页面 圈出来的地方显 ...

  9. swoole(PHP异步网络通信引擎)的结构和运行流程

    swoole结构说明和运行流程 主要分为三个部分: 1.Master:swoole的主进程 处理swoole核心的事件驱动, 它包含多个线程(蓝色Reactor), 所有事件的监听都在Reactor实 ...

  10. Java之函数式接口@FunctionalInterface详解(附源码)

    Java之函数式接口@FunctionalInterface详解 函数式接口的定义 在java8中,满足下面任意一个条件的接口都是函数式接口: 1.被@FunctionalInterface注释的接口 ...