SpringBoot2.x操作缓存的新姿势
一、介绍
spring cache 是spring3版本之后引入的一项技术,可以简化对于缓存层的操作,spring cache与springcloud stream类似,都是基于抽象层,可以任意切换其实现。其核心是CacheManager
、Cache
这两个接口,所有由spring整合的cache都要实现这两个接口、Redis的实现类则是 RedisCache
和 RedisManager。
二、使用
Ⅰ、查询
需要导入的依赖
<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操作缓存的新姿势的更多相关文章
- 【转+自己研究】新姿势之Docker Remote API未授权访问漏洞分析和利用
0x00 概述 最近提交了一些关于 docker remote api 未授权访问导致代码泄露.获取服务器root权限的漏洞,造成的影响都比较严重,比如 新姿势之获取果壳全站代码和多台机器root权限 ...
- Broadcom BCM94352z/DW1560驱动新姿势
转自:https://blog.daliansky.net/Broadcom-BCM94352z-DW1560-drive-new-posture.html Broadcom WiFi/BlueToo ...
- vue组件通信新姿势
在vue项目实际开发中我们经常会使用props和emit来进行子父组件的传值通信,父组件向子组件传递数据是通过prop传递的, 子组件传递数据给父组件是通过$emit触发事件来做到的.例如: Vue. ...
- Java计时新姿势
为获得更好的阅读体验,请访问原文:传送门 前言: 最近公司来了个大佬,从他那里学到不少东西,其中一个就是计时 的新姿势「StopWatch」,赶紧来一起了解了解吧! 一.最简单的计时 在我们的程序中不 ...
- FJNU 1159 Fat Brother’s new way(胖哥的新姿势)
FJNU 1159 Fat Brother’s new way(胖哥的新姿势) Time Limit: 1000MS Memory Limit: 257792K [Description] [题目 ...
- [Cache] C#操作缓存--CacheHelper缓存帮助类 (转载)
点击下载 CacheHelper.zip CacheHelper 缓存帮助类 C#怎么操作缓存 怎么设置和取缓存数据,都在这个类里面呢 下面看一下代码吧 /// <summary> /// ...
- JSON CSRF新姿势
以前做渗透测试,遇到过很多次POST数据为JSON数据的CSRF,一直没有搞定,最近发现一个新姿势, 本文作者:Mannix@安全文库 微信公众号:安全文库 测试的时候,当应用程序验证了Cont ...
- 转载 Python 操作 MySQL 的正确姿势 - 琉璃块
Python 操作 MySQL 的正确姿势 收录待用,修改转载已取得腾讯云授权 作者 |邵建永 编辑 | 顾乡 使用Python进行MySQL的库主要有三个,Python-MySQL(更熟悉的名字可能 ...
- bzoj1656: [Usaco2006 Jan] The Grove 树木 (bfs+新姿势)
题目大意:一个n*m的图中,“.”可走,“X”不可走,“*”为起点,问从起点开始绕所有X一圈回到起点最少需要走多少步. 一开始看到这题,自己脑洞了下怎么写,应该是可过,然后跑去看了题解,又学会了一 ...
随机推荐
- PHP的一些安全设置
小伙伴们新年好啊,又有半个月没有更新博客了.更新也比较随性,想起什么就写点什么,方便和大家工作同学习总结. 最近和同事说起了PHP安全相关的问题,记录下一些心得体会. 由于脚本语言和早期版本设计的诸多 ...
- Java框架之Spring01-IOC-bean配置-文件引入-注解装配
Spring 框架,即framework.是对特定应用领域中的应用系统的部分设计和实现的整体结构.就相当于让别人帮你完成一些基础工作,它可以处理系统很多细节问题,而且框架一般是成熟,稳健的. Spri ...
- MQ使用:apollo和rabbitmq
apollo apollo 是一个更快.更可靠.更容易维护的消息代理,它是由最初的ActiveMQ的基础构建的.它使用一个完全不同的线程和消息调度架构来实现这一点.与ActiveMQ一样,apollo ...
- 搞定SpringBoot多数据源(2):动态数据源
目录 1. 引言 2. 动态数据源流程说明 3. 实现动态数据源 3.1 说明及数据源配置 3.1.1 包结构说明 3.1.2 数据库连接信息配置 3.1.3 数据源配置 3.2 动态数据源设置 3. ...
- 256位AES加密和解密
/// <summary> /// 256位AES加密 /// </summary> /// <param name="toEncrypt">& ...
- 洛谷p1502窗口的星星 扫描线
题目链接:https://www.luogu.org/problem/P1502 扫描线的板子题,把每个点看成矩形,存下边(x,y,y+h-1,li)和(x+w-1,y,y+h-1),在按横坐标扫线段 ...
- 使用eNSP配置QinQ
参考链接:https://blog.csdn.net/alone_map/article/details/52217094 本文主要记录使用华为eNSP模拟器来实现配置QinQ,并对QinQ的报文进行 ...
- 推荐一个学java的网站
最近在接触Java发现一个可以用来学习的 很不错的网站 直接扔链接 http://how2j.cn?p=77451
- HGE引擎改进
基于HGEDX9版本修改. hge库: 1.全UNICODE化 2.增加时间模块:Timer_StartTick(),Timer_NowTick()等六个函数 3.增加服从正态分布的随机数生成函数:R ...
- Docker和Kubernetes
Docker和Kubernetes Docker Docker是一个容器的开放平台,但它不是最早的.自20世纪70年代以来,容器平台一直存在.他们的开发可以追溯到Unix中的chroot系统调用.在2 ...