玩转 SpringBoot2.x 之缓存对象 | 原力计划
作者 | 桌前明月
来源 | CSDN博客
头图 | 付费下载自视觉中国
出品 | CSDN(ID:CSDNnews)
前言
提到Redis 大部分的人首先想到的可能就是缓存,那么在 Java 项目中如何把对象缓存起来呢?这就是本文接下来要介绍的内容:缓存对象。本文通过SpringBoot 项目带你快速了解通过Jedis 把对象缓存到Redis中。
阅读本文需要你了解如何搭建 SpringBoot 项目即可,另外需要了解的是本文SpringBoot 版本是 2.1.0.RELEASE。关于SpringBoot 集成 Jedis 请参考:玩转 SpringBoot 2.x 之 快速集成 Jedis客户端(普通版)
接下来就让我们开始具体的代码案例介绍吧!
代码案例
演示通过将下面的 User 类创建的对象缓存到 Redis 中,具体有2种方式:序列化、Json。User 类具体代码如下:
1public class User implements Serializable {23 private String name;4 private Integer age;56 public User(String name,Integer age){7 this.name = name;8 this.age = age;9 }
10 //省略 getter and setter 方法
11}
关于 过期时间处理和返回Jedis 线程操作到线程池操作封装到了 JedisCacheServiceSupport 中,具体代码如下:
1public abstract class JedisCacheServiceSupport {2 public static final long EXPIRE_MILLISECONDS_DEFAULT_LONG = 3*60*60*1000;34 public Long getExpireTime(Long expireTime) {5 expireTime = (expireTime == null || expireTime.longValue() <= 0) ? EXPIRE_MILLISECONDS_DEFAULT_LONG : expireTime;6 return expireTime;7 }89 public void close(Jedis jedis){
10 if(jedis != null){
11 jedis.close();
12 }
13 }
14}
序列化方式
序列化的方式通过现将对象转换成二进制的流(序列化)后保存到 Redis 中,然后通过key 获取到二进制,在把二进制流转换成对象(反序列化)。
保存对象的具体操作如下:
通过 ObjectOutputStream.writeObject(object) 将User 对象转换成byte 数组,然后通过 psetex(byte[] key, long milliseconds, byte[] value) 将 byte[] 数组存入Redis中。其中
byte[] key:需要将key 转换成byte数组。
long milliseconds:是对象在Redis 中存活的时间,以毫秒为单位。
byte[] value:对象转换成的btye 数组。
获取对象的具体操作如下:
通过 get(byte[] key) 获取 User 对象转换的byte 数组,然后通过 ObjectInputStream.readObject() 将数组转换成User对象。
通过序列化方式保存和获取对象具体代码如下:
1@Service2public class JedisCacheService extends JedisCacheServiceSupport {34 private static Logger logger = LoggerFactory.getLogger(JedisCacheService.class);5678 @Autowired9 private JedisPool jedisPool;1011 /**12 * 获取缓存中的对象13 * @param key14 * @return15 */16 public Object getObject(String key) {17 Jedis jedis = null;18 Object object = null;19 try {20 jedis = jedisPool.getResource();21 byte[] ObjectByteArray = jedis.get(key.getBytes());22 object = unserialize(ObjectByteArray);23 }catch (Exception e){24 e.printStackTrace();25 }finally {26 close(jedis);27 }28 return object;29 }3031 /**32 * 将对象缓存到Redis中,设置默认过期时间33 * @param key34 * @param value35 */36 public void putObject(String key, Object value) {37 putObject(key,value,null);38 }39 /**40 * 将对象缓存到Redis中,自定义认过期时间41 * @param key42 * @param value43 */44 public void putObject(String key, Object value, Long expireTime) {45 Jedis jedis = null;46 try {47 jedis = jedisPool.getResource();48 jedis.psetex(key.getBytes(),getExpireTime(expireTime),serialize(value));49 }catch (Exception e){50 e.printStackTrace();51 }finally {52 close(jedis);53 }54 }555657 /**58 * 序列化59 * @param object60 * @return61 */62 public static byte[] serialize(Object object) {63 ObjectOutputStream oos = null;64 ByteArrayOutputStream baos = null;65 try {66 baos = new ByteArrayOutputStream();67 oos = new ObjectOutputStream(baos);68 oos.writeObject(object);69 byte[] bytes = baos.toByteArray();70 return bytes;71 } catch (Exception e) {72 logger.error(e.getMessage(), e);73 } finally {74 IOUtil.closeStream(oos);75 IOUtil.closeStream(baos);76 }77 return null;78 }7980 /**81 * 反序列化82 * @param bytes83 * @return84 */85 public static Object unserialize(byte[] bytes) {86 if (bytes == null) return null;8788 ByteArrayInputStream bais = null;89 ObjectInputStream ois = null;90 try {91 bais = new ByteArrayInputStream(bytes);92 ois = new ObjectInputStream(bais);93 return ois.readObject();94 } catch (Exception e) {95 logger.error(e.getMessage(), e);96 } finally {97 IOUtil.closeStream(bais);98 IOUtil.closeStream(ois);99 }
100 return null;
101 }
102}
关闭 输入流和输出流工具类具体代码如下:
1public class IOUtil {2 public static void closeStream(InputStream inputStream) {3 if (inputStream != null) {4 try {5 inputStream.close();6 } catch (IOException e) {7 e.printStackTrace();8 }9
10 }
11 }
12
13 public static void closeStream(OutputStream outputStream) {
14 if (outputStream != null) {
15 try {
16 outputStream.close();
17 } catch (IOException e) {
18 e.printStackTrace();
19 }
20
21 }
22 }
23}
序列化方式演示
测试 JedisCacheService putObject(将对象放入缓存中)、getObject(从缓存中获取对象),具体代码如下:
1@RunWith(SpringRunner.class)2@SpringBootTest3public class JedisCacheServiceTest {4 private Logger logger = LoggerFactory.getLogger(JedisCacheService.class);5 @Autowired6 private JedisCacheService jedisCacheService;78 @Test9 public void putObject() {
10 User user = new User("zhuoqiammingyue",19);
11 jedisCacheService.putObject("user01",user);
12 logger.info("缓存用户成功!");
13 }
14
15 @Test
16 public void getObject() {
17 User user = (User)jedisCacheService.getObject("user01");
18 logger.info("User name={},age={}",user.getName(),user.getAge());
19 }
20}
putObject 日志信息:
12020-02-26 22:08:50.320 INFO 26748 --- [ main] cn.lijunkui.cache.JedisCacheServiceTest : Started JedisCacheServiceTest in 7.157 seconds (JVM running for 9.357)
22020-02-26 22:08:51.144 INFO 26748 --- [ main] cn.lijunkui.cache.JedisCacheService : 缓存用户成功!
getObject 日志信息:
12020-02-26 22:09:57.492 INFO 9612 --- [ main] cn.lijunkui.cache.JedisCacheServiceTest : Started JedisCacheServiceTest in 7.07 seconds (JVM running for 8.902)
22020-02-26 22:09:58.143 INFO 9612 --- [ main] cn.lijunkui.cache.JedisCacheService : User name=zhuoqiammingyue,age=19
Json 方式
Json 的方式是将对象转换成可阅读的Json 串后保存到 Redis 中,然后通过key 获取到Json 串,在把Json 串成对象。对象转成成Json串是通过谷歌的Gson 完成的,所以需要引入Gson的依赖,具体依赖代码如下:
1<dependency>
2 <groupId>com.google.code.gson</groupId>
3 <artifactId>gson</artifactId>
4 <version>2.8.5</version>
5</dependency>
Json 保存对象的具体操作如下:
通过 Gson.toJson(Object src) 将User 对象转换成 Json串,然后通过 psetex(String key, long milliseconds, String value) 将 Json串存入Redis中。
Json 获取对象的具体操作如下:
通过 get(String key) 获取 User 对象的Json串,然后通过 Gson.fromJson(String json, Class<T> classOfT) 将Json串转换成User对象。
通过Json 方式保存和获取对象具体代码如下:
1@Service2public class JedisJsonCacheService extends JedisCacheServiceSupport {34 private static Logger logger = LoggerFactory.getLogger(JedisJsonCacheService.class);56 @Autowired7 private JedisPool jedisPool;89 /**
10 * 获取缓存中的对象
11 * @param key
12 * @param clazz
13 * @return
14 */
15 public Object getObject(String key,Class clazz) {
16 Jedis jedis = null;
17 Object object = null;
18 try {
19 jedis = jedisPool.getResource();
20 String objectJson = jedis.get(key);
21 object = toObjce(objectJson,clazz);
22 }catch (Exception e){
23 e.printStackTrace();
24 }finally {
25 close(jedis);
26 }
27 return object;
28 }
29
30 /**
31 * 将对象缓存到Redis中,设置默认过期时间
32 * @param key
33 * @param value
34 */
35 public void putObject(String key, Object value) {
36 putObject(key, value,null);
37 }
38
39 /**
40 * 将对象缓存到Redis中,自定义认过期时间
41 * @param key
42 * @param value
43 * @param expireTime
44 */
45 public void putObject(String key, Object value, Long expireTime) {
46 Jedis jedis = null;
47 try {
48 jedis = jedisPool.getResource();
49 jedis.psetex(key,getExpireTime(expireTime),toJson(value));
50 }catch (Exception e){
51 e.printStackTrace();
52 }finally {
53 close(jedis);
54 }
55 }
56
57
58
59 /**
60 * 将对象转换成Json串
61 * @param value
62 * @return
63 */
64 private String toJson(Object value) {
65 Gson gson = new Gson();
66 return gson.toJson(value);
67 }
68
69 /**
70 * 将Json串转换成对象
71 * @param json
72 * @param clazz
73 * @return
74 */
75 private Object toObjce(String json,Class clazz) {
76 Gson gson = new Gson();
77 return gson.fromJson(json,clazz);
78 }
79}
序列化方式演示
测试 JedisJsonCacheServiceTest putObject(将对象放入缓存中)、getObject(从缓存中获取对象),具体代码如下:
1@RunWith(SpringRunner.class)2@SpringBootTest3public class JedisJsonCacheServiceTest {45 private Logger logger = LoggerFactory.getLogger(JedisJsonCacheServiceTest.class);6 @Autowired7 private JedisJsonCacheService jedisJsonCacheService;89 @Test
10 public void putObject() {
11 User user = new User("zhuoqiammingyue2",20);
12 jedisJsonCacheService.putObject("user02",user);
13 logger.info("缓存用户成功!");
14 }
15
16 @Test
17 public void getObject() {
18 User user = (User)jedisJsonCacheService.getObject("user02",User.class);
19 logger.info("User name={},age={}",user.getName(),user.getAge());
20 }
21}
putObject 日志信息:
12020-02-27 07:57:16.184 INFO 3692 --- [ main] c.l.cache.JedisJsonCacheServiceTest : Started JedisJsonCacheServiceTest in 7.92 seconds (JVM running for 10.786)
22020-02-27 07:57:16.852 INFO 3692 --- [ main] c.l.cache.JedisJsonCacheServiceTest : 缓存用户成功!
getObject 日志信息:
12020-02-27 07:57:56.359 INFO 27624 --- [ main] c.l.cache.JedisJsonCacheServiceTest : Started JedisJsonCacheServiceTest in 7.364 seconds (JVM running for 9.256)
22020-02-27 07:57:56.824 INFO 27624 --- [ main] c.l.cache.JedisJsonCacheServiceTest : User name=zhuoqiammingyue2,age=20
小结
序列化和Json这2种方式,在实际开发中可以根据你的喜好自行选择。Json 方式使用的是Gson 当然你也可以使用 FastJson ,序列化采用了 Java 原生的序列化和反序列化,同时你也可以切换成效率更高的 Hessian 进行序列化和反序列化。
代码示例
我本地环境如下:
SpringBoot Version: 2.1.0.RELEASE
Apache Maven Version:3.6.0
Java Version:1.8.0_144
IDEA:IntellJ IDEA
操作过程如出现问题可以在我的GitHub 仓库 springbootexamples 中模块名为 spring-boot-2.x-redis-jedis-objectcache 项目中进行对比查看
GitHub:https://github.com/zhuoqianmingyue/springbootexamples
原文链接:https://blog.csdn.net/ljk126wy/article/details/104519059
【End】
《原力计划【第二季】- 学习力挑战》正式开始!
即日起至 3月21日,千万流量支持原创作者,更有专属【勋章】等你来挑战
推荐阅读
☞微信 QQ 小程序因违规被封;微软大破全球最大僵尸网络;VS Code 1.43 发布 | 极客头条
☞官宣!阿里进军 5G,成立 XG 实验室发力新基建
☞前沿技术探秘:知识图谱构建流程及方法
☞留德武汉程序员在疫区:凌晨下载数据,网速影响工作
☞云原生的漏洞与威胁有哪些?云原生安全性如何?这里有你想知道的一切!
☞编程小白模拟简易比特币系统,手把手带你写一波!(附代码) | 博文精选
你点的每一个在看,我认真当成了喜欢
玩转 SpringBoot2.x 之缓存对象 | 原力计划相关推荐
- 玩转SpringBoot2.x之缓存对象
前言 提到Redis 大部分的人首先想到的可能就是缓存,那么在 Java 项目中如何把对象缓存起来呢?这就是本文接下来要介绍的内容:缓存对象.本文通过SpringBoot 项目带你快速了解通过Jedi ...
- 获取对象的key_玩转 SpringBoot2.x 之缓存对象
作者 | 桌前明月 来源 | CSDN博客 头图 | 付费下载自视觉中国 出品 | CSDN(ID:CSDNnews) 前言 提到Redis 大部分的人首先想到的可能就是缓存,那么在 Java 项目中 ...
- mybatis mapper.xml 文件共用_MyBatis 缓存原来是这么一回事儿!| 原力计划
作者 | Lw中责编 | 夕颜出品 | CSDN(ID:CSDNnews) 什么是缓存? 缓存就是存储数据的一个地方(称作:Cache),当程序要读取数据时,会首先从缓存中获取,有则直接返回,否则从其 ...
- MyBatis 缓存原来是这么一回事儿!| 原力计划
作者 | Lw中 责编 | 夕颜 出品 | CSDN(ID:CSDNnews) 什么是缓存? 缓存就是存储数据的一个地方(称作:Cache),当程序要读取数据时,会首先从缓存中获取,有则直接返回,否则 ...
- Java 那些最常用的工具类库 | 原力计划
作者 | Java 识堂 责编 | 屠敏 出品 | CSDN(ID:CSDNnews) Apache Commons Apache Commons有很多子项目,常用的项目如下: BeanUtils ...
- Python2 倒计时,还不快来掌握 Python3 酷炫的新特性? | 原力计划
作者 | 云爬虫技术研究笔记 责编 | 郭芮 出品 | CSDN 博客 Python3.8已经发布近一个月了,距离Python3.0第一个版本发布也将超过10年了.相信很多人还是依旧在使用Python ...
- 面试官:你连 RESTful 都不知道我怎么敢要你?| 原力计划
作者 | zhanglinblog 责编 | 刘静 出品 | CSDN 博客 面试官:了解RESTful吗? 我:听说过. 面试官:那什么是RESTful? 我:就是用起来很规范,挺好的 面试官:是R ...
- 找不到libmmd.dll无法继续执行代码_300 行代码带你秒懂 Java 多线程!| 原力计划...
作者 | 永远在路上[] 责编 | 胡巍巍 出品 | CSDN博客 线程线程的概念,百度是这样解释的:线程(英语:Thread)是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际 ...
- Spring 从入门到入土——AOP 就这么简单!| 原力计划
作者| 冢狐 责编 | 夕颜 出品 | CSDN博客 什么是AOP? 面向切面编程(Aspect Oriented Programming),通过预编译的方式和运行期动态代理实现程序功能的统一维护的 ...
最新文章
- 如何比较浮点数相等_『GCTT 出品』Go 语言中的比较操作符
- UVa OJ 120
- fscanf和feof的组合使用
- 网络营销第一课:市场营销基础(2)
- IOS开发之格式化日期时间的使用 编程中常见问题
- Programming Assignment 5: Burrows–Wheeler Data Compression
- 《ETL原理及应用》学习笔记 ·003【kettle的使用-1】
- Flash Builder 找不到Adobe Flash Player或者Flash Builder 找不到debug版本的解决方法
- Java Bitwise Operators
- 《自己动手写操作系统》第二章——Bochs调试及相关仿真工具的使用方法
- 工具学习——在线访问远程服务器的SSH工具
- poj2387(Dijkstra)
- LVDS的接口电路设计
- 如何检测显卡类型和OpenGL版本
- RocketMQ中文文档(译)
- 新产品、新特性、新生态丨一文回顾openGauss峰会云和恩墨分论坛150分钟的精彩...
- shell脚本实践:自动清理文件,以时间方式形成路径的图片或者是Excel、pdf等文件
- Go语言开发k8s-04-Service操作
- 解决由于权限问题导致YUM安装失败
- Hive 常用日期处理-昨天、本月、上月同期、去年同期、月初、月末等
热门文章
- BUPT 2012复试机考 2T
- IOS 获取系统通讯录中的联系人信息
- Android重力感应示例
- 输出最长上升子序列 模型(DP)
- spinningup 绘制曲线
- 【深度学习】【U-net】医学图像(血管)分割实验记录
- 下一较大值(一,二)
- win10+cuda10.0.130+cudnn7.5.1+tensorflow-gpu 1.13.1+anaconda3+keras+pycharm2018
- python的常量变量_Python基础语法-常量与变量
- Tensorflow卷积神经网络识别MINST手写数字