玩转SpringBoot2.x之缓存对象
前言
提到Redis 大部分的人首先想到的可能就是缓存,那么在 Java 项目中如何把对象缓存起来呢?这就是本文接下来要介绍的内容:缓存对象。本文通过SpringBoot 项目带你快速了解通过Jedis 把对象缓存到Redis中。
阅读本文需要你了解如何搭建 SpringBoot 项目即可,另外需要了解的是本文SpringBoot 版本是 2.1.0.RELEASE。关于SpringBoot 集成 Jedis 请参考:玩转 SpringBoot 2.x 之 快速集成 Jedis客户端(普通版)
接下来就让我们开始具体的代码案例介绍吧!
代码案例
演示通过将下面的 User 类创建的对象缓存到 Redis 中,具体有2种方式:序列化、Json。User 类具体代码如下:
public class User implements Serializable {private String name;private Integer age;public User(String name,Integer age){this.name = name;this.age = age;}//省略 getter and setter 方法
}
关于 过期时间处理和返回Jedis 线程操作到线程池操作封装到了 JedisCacheServiceSupport 中,具体代码如下:
public abstract class JedisCacheServiceSupport {public static final long EXPIRE_MILLISECONDS_DEFAULT_LONG = 3*60*60*1000;public Long getExpireTime(Long expireTime) {expireTime = (expireTime == null || expireTime.longValue() <= 0) ? EXPIRE_MILLISECONDS_DEFAULT_LONG : expireTime;return expireTime;}public void close(Jedis jedis){if(jedis != null){jedis.close();}}
}
序列化方式
序列化的方式通过现将对象转换成二进制的流(序列化)后保存到 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对象。
通过序列化方式保存和获取对象具体代码如下:
@Service
public class JedisCacheService extends JedisCacheServiceSupport {private static Logger logger = LoggerFactory.getLogger(JedisCacheService.class);@Autowiredprivate JedisPool jedisPool;/*** 获取缓存中的对象* @param key* @return*/public Object getObject(String key) {Jedis jedis = null;Object object = null;try {jedis = jedisPool.getResource();byte[] ObjectByteArray = jedis.get(key.getBytes());object = unserialize(ObjectByteArray);}catch (Exception e){e.printStackTrace();}finally {close(jedis);}return object;}/*** 将对象缓存到Redis中,设置默认过期时间* @param key* @param value*/public void putObject(String key, Object value) {putObject(key,value,null);}/*** 将对象缓存到Redis中,自定义认过期时间* @param key* @param value*/public void putObject(String key, Object value, Long expireTime) {Jedis jedis = null;try {jedis = jedisPool.getResource();jedis.psetex(key.getBytes(),getExpireTime(expireTime),serialize(value));}catch (Exception e){e.printStackTrace();}finally {close(jedis);}}/*** 序列化* @param object* @return*/public static byte[] serialize(Object object) {ObjectOutputStream oos = null;ByteArrayOutputStream baos = null;try {baos = new ByteArrayOutputStream();oos = new ObjectOutputStream(baos);oos.writeObject(object);byte[] bytes = baos.toByteArray();return bytes;} catch (Exception e) {logger.error(e.getMessage(), e);} finally {IOUtil.closeStream(oos);IOUtil.closeStream(baos);}return null;}/*** 反序列化* @param bytes* @return*/public static Object unserialize(byte[] bytes) {if (bytes == null) return null;ByteArrayInputStream bais = null;ObjectInputStream ois = null;try {bais = new ByteArrayInputStream(bytes);ois = new ObjectInputStream(bais);return ois.readObject();} catch (Exception e) {logger.error(e.getMessage(), e);} finally {IOUtil.closeStream(bais);IOUtil.closeStream(ois);}return null;}
}
关闭 输入流和输出流工具类具体代码如下:
public class IOUtil {public static void closeStream(InputStream inputStream) {if (inputStream != null) {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}}public static void closeStream(OutputStream outputStream) {if (outputStream != null) {try {outputStream.close();} catch (IOException e) {e.printStackTrace();}}}
}
序列化方式演示
测试 JedisCacheService putObject(将对象放入缓存中)、getObject(从缓存中获取对象),具体代码如下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class JedisCacheServiceTest {private Logger logger = LoggerFactory.getLogger(JedisCacheService.class);@Autowiredprivate JedisCacheService jedisCacheService;@Testpublic void putObject() {User user = new User("zhuoqiammingyue",19);jedisCacheService.putObject("user01",user);logger.info("缓存用户成功!");}@Testpublic void getObject() {User user = (User)jedisCacheService.getObject("user01");logger.info("User name={},age={}",user.getName(),user.getAge());}
}
putObject 日志信息:
2020-02-26 22:08:50.320 INFO 26748 --- [ main] cn.lijunkui.cache.JedisCacheServiceTest : Started JedisCacheServiceTest in 7.157 seconds (JVM running for 9.357)
2020-02-26 22:08:51.144 INFO 26748 --- [ main] cn.lijunkui.cache.JedisCacheService : 缓存用户成功!
getObject 日志信息:
2020-02-26 22:09:57.492 INFO 9612 --- [ main] cn.lijunkui.cache.JedisCacheServiceTest : Started JedisCacheServiceTest in 7.07 seconds (JVM running for 8.902)
2020-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的依赖,具体依赖代码如下:
<dependency><groupId>com.google.code.gson</groupId><artifactId>gson</artifactId><version>2.8.5</version>
</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 方式保存和获取对象具体代码如下:
@Service
public class JedisJsonCacheService extends JedisCacheServiceSupport {private static Logger logger = LoggerFactory.getLogger(JedisJsonCacheService.class);@Autowiredprivate JedisPool jedisPool;/*** 获取缓存中的对象* @param key* @param clazz* @return*/public Object getObject(String key,Class clazz) {Jedis jedis = null;Object object = null;try {jedis = jedisPool.getResource();String objectJson = jedis.get(key);object = toObjce(objectJson,clazz);}catch (Exception e){e.printStackTrace();}finally {close(jedis);}return object;}/*** 将对象缓存到Redis中,设置默认过期时间* @param key* @param value*/public void putObject(String key, Object value) {putObject(key, value,null);}/*** 将对象缓存到Redis中,自定义认过期时间* @param key* @param value* @param expireTime*/public void putObject(String key, Object value, Long expireTime) {Jedis jedis = null;try {jedis = jedisPool.getResource();jedis.psetex(key,getExpireTime(expireTime),toJson(value));}catch (Exception e){e.printStackTrace();}finally {close(jedis);}}/*** 将对象转换成Json串* @param value* @return*/private String toJson(Object value) {Gson gson = new Gson();return gson.toJson(value);}/*** 将Json串转换成对象* @param json* @param clazz* @return*/private Object toObjce(String json,Class clazz) {Gson gson = new Gson();return gson.fromJson(json,clazz);}
}
序列化方式演示
测试 JedisJsonCacheServiceTest putObject(将对象放入缓存中)、getObject(从缓存中获取对象),具体代码如下:
@RunWith(SpringRunner.class)
@SpringBootTest
public class JedisJsonCacheServiceTest {private Logger logger = LoggerFactory.getLogger(JedisJsonCacheServiceTest.class);@Autowiredprivate JedisJsonCacheService jedisJsonCacheService;@Testpublic void putObject() {User user = new User("zhuoqiammingyue2",20);jedisJsonCacheService.putObject("user02",user);logger.info("缓存用户成功!");}@Testpublic void getObject() {User user = (User)jedisJsonCacheService.getObject("user02",User.class);logger.info("User name={},age={}",user.getName(),user.getAge());}
}
putObject 日志信息:
2020-02-27 07:57:16.184 INFO 3692 --- [ main] c.l.cache.JedisJsonCacheServiceTest : Started JedisJsonCacheServiceTest in 7.92 seconds (JVM running for 10.786)
2020-02-27 07:57:16.852 INFO 3692 --- [ main] c.l.cache.JedisJsonCacheServiceTest : 缓存用户成功!
getObject 日志信息:
2020-02-27 07:57:56.359 INFO 27624 --- [ main] c.l.cache.JedisJsonCacheServiceTest : Started JedisJsonCacheServiceTest in 7.364 seconds (JVM running for 9.256)
2020-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
玩转SpringBoot2.x之缓存对象相关推荐
- 玩转 SpringBoot2.x 之缓存对象 | 原力计划
作者 | 桌前明月 来源 | CSDN博客 头图 | 付费下载自视觉中国 出品 | CSDN(ID:CSDNnews) 前言 提到Redis 大部分的人首先想到的可能就是缓存,那么在 Java 项目中 ...
- 获取对象的key_玩转 SpringBoot2.x 之缓存对象
作者 | 桌前明月 来源 | CSDN博客 头图 | 付费下载自视觉中国 出品 | CSDN(ID:CSDNnews) 前言 提到Redis 大部分的人首先想到的可能就是缓存,那么在 Java 项目中 ...
- 利用python获取指定url在ATS中缓存对象的信息
业务需求 给定url,如何查询指定的ATS中是否有该url的缓存对象信息?如果缓存了的话,希望提供该缓存对象的大小,缓存时间,缓存文件名,缓存份数(document alternative)等等信息 ...
- openGL 入门 2--顶点数组对象 VAO 和 缓存对象 VBO
用户输入的数据 以 顶点数组对象表示 Vertex Array Object,VAO void glGenVertexArrays(GLsizei n, GLuint *arrays); 返回 n个 ...
- opengles2.0 帧缓存对象(FBO)
opengles2.0 帧缓存对象(FBO) 帧缓存对象(fbo)主要是用于做渲染到纹理. opengles2.0渲染到纹理的方法有三种: 第一,使用glCopyTexImage2D或者glCopyT ...
- OpenGL帧缓存对象(FBO:Frame Buffer Object)(转载)
原文地址http://www.songho.ca/opengl/gl_fbo.html 但有改动. OpenGL Frame BufferObject(FBO) Overview: 在OpenGL渲染 ...
- java用redis缓存的步骤_详解在Java程序中运用Redis缓存对象的方法|chu
这段时间一直有人问如何在Redis中缓存Java中的List 集合数据,其实很简单,常用的方式有两种: 1. 利用序列化,把对象序列化成二进制格式,Redis 提供了 相关API方法存储二进制,取数据 ...
- java oscache 缓存_Java]用OSCache进行缓存对象
Java]用OSCache进行缓存对象 1.OSCache是什么? OSCache标记库由OpenSymphony设计,它是一种开创性的缓存方案,它提供了在现有JSP页面之内实现内存缓存的功能.OSC ...
- 玩转springboot2.x之异步调用@Async
专题系列分类:玩转SpringBoot2.x系列教程 我们在正常开发中一般都是通过同步的方式进行处理的,但是有时候执行多个任务并不是都需要一起执行完才行,采取异步的方式可以有效提升一个请求响应的时间. ...
最新文章
- HTML中的link的简单介绍和用法
- 《Photoshop Lightroom4 经典教程》—第2课2.2节切换屏幕模式
- 面向对象的C语言编程-DynamicLinkageGenericFunctions--C语言中的偷梁换柱
- html5和前端精要(1)-架构与基础(1)
- git diff old mode 100644 new mode 100755
- g++编译时:No such file or directory
- python 字符串翻转
- unix网络编程 str_cli epoll 非阻塞版本
- 【机器学习】逻辑回归—良/恶性乳腺癌肿瘤预测
- java后台调用SOE时,报异常java.io.IOException: Attempted read from closed stream
- FutureWarning: Passing (type 1) or 1type as a synonym of type is deprecated in a future vers 的解决
- Web性能瓶颈查找经验总结
- loader-wizard.php,ioncube扩展loader-wizard的安装详细图文教程
- Sicily 1094 Cude解题报告
- SQLServer中如何高效解析JSON格式数据
- 2014江西理工大学C语言程序竞赛高级组
- php session fixation,Session Fixation 攻防实战(图)
- Ubuntu中程序崩溃,杀死进程方法
- 内存重叠的拷贝--memmove
- Android 华为手机10.1 启动service Service starting has been prevented by iaware or trustsbase **
热门文章
- qlabel 显示图片后大小不变_图形编程:QT使用scrollarea显示图片的解决方案
- MySQL迁移安装_mysql数据库安装路径迁移
- c语言学习进阶-C语言程序实现矩阵乘法
- 使用TensorFlow.js进行人脸触摸检测第2部分:使用BodyPix
- Angular和.NET Core Web API入门应用程序
- Fedora 31 及以后版本将不再支持 32 位内核已实锤
- kali怎么进入root用户_linux中怎么进入root用户
- linux hadoop namenode_HADOOP_HDFS伪分布式安装步骤
- idea中实体类右击没有ptg_这些6到飞起的idea插件,你还没用过?
- oracle 时间按季度,ORACLE时间字段取年、月、日、季度