前言

提到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之缓存对象相关推荐

  1. 玩转 SpringBoot2.x 之缓存对象 | 原力计划

    作者 | 桌前明月 来源 | CSDN博客 头图 | 付费下载自视觉中国 出品 | CSDN(ID:CSDNnews) 前言 提到Redis 大部分的人首先想到的可能就是缓存,那么在 Java 项目中 ...

  2. 获取对象的key_玩转 SpringBoot2.x 之缓存对象

    作者 | 桌前明月 来源 | CSDN博客 头图 | 付费下载自视觉中国 出品 | CSDN(ID:CSDNnews) 前言 提到Redis 大部分的人首先想到的可能就是缓存,那么在 Java 项目中 ...

  3. 利用python获取指定url在ATS中缓存对象的信息

    业务需求 给定url,如何查询指定的ATS中是否有该url的缓存对象信息?如果缓存了的话,希望提供该缓存对象的大小,缓存时间,缓存文件名,缓存份数(document alternative)等等信息 ...

  4. openGL 入门 2--顶点数组对象 VAO 和 缓存对象 VBO

    用户输入的数据 以 顶点数组对象表示 Vertex Array Object,VAO void glGenVertexArrays(GLsizei n, GLuint *arrays); 返回 n个 ...

  5. opengles2.0 帧缓存对象(FBO)

    opengles2.0 帧缓存对象(FBO) 帧缓存对象(fbo)主要是用于做渲染到纹理. opengles2.0渲染到纹理的方法有三种: 第一,使用glCopyTexImage2D或者glCopyT ...

  6. OpenGL帧缓存对象(FBO:Frame Buffer Object)(转载)

    原文地址http://www.songho.ca/opengl/gl_fbo.html 但有改动. OpenGL Frame BufferObject(FBO) Overview: 在OpenGL渲染 ...

  7. java用redis缓存的步骤_详解在Java程序中运用Redis缓存对象的方法|chu

    这段时间一直有人问如何在Redis中缓存Java中的List 集合数据,其实很简单,常用的方式有两种: 1. 利用序列化,把对象序列化成二进制格式,Redis 提供了 相关API方法存储二进制,取数据 ...

  8. java oscache 缓存_Java]用OSCache进行缓存对象

    Java]用OSCache进行缓存对象 1.OSCache是什么? OSCache标记库由OpenSymphony设计,它是一种开创性的缓存方案,它提供了在现有JSP页面之内实现内存缓存的功能.OSC ...

  9. 玩转springboot2.x之异步调用@Async

    专题系列分类:玩转SpringBoot2.x系列教程 我们在正常开发中一般都是通过同步的方式进行处理的,但是有时候执行多个任务并不是都需要一起执行完才行,采取异步的方式可以有效提升一个请求响应的时间. ...

最新文章

  1. HTML中的link的简单介绍和用法
  2. 《Photoshop Lightroom4 经典教程》—第2课2.2节切换屏幕模式
  3. 面向对象的C语言编程-DynamicLinkageGenericFunctions--C语言中的偷梁换柱
  4. html5和前端精要(1)-架构与基础(1)
  5. git diff old mode 100644 new mode 100755
  6. g++编译时:No such file or directory
  7. python 字符串翻转
  8. unix网络编程 str_cli epoll 非阻塞版本
  9. 【机器学习】逻辑回归—良/恶性乳腺癌肿瘤预测
  10. java后台调用SOE时,报异常java.io.IOException: Attempted read from closed stream
  11. FutureWarning: Passing (type 1) or 1type as a synonym of type is deprecated in a future vers 的解决
  12. Web性能瓶颈查找经验总结
  13. loader-wizard.php,ioncube扩展loader-wizard的安装详细图文教程
  14. Sicily 1094 Cude解题报告
  15. SQLServer中如何高效解析JSON格式数据
  16. 2014江西理工大学C语言程序竞赛高级组
  17. php session fixation,Session Fixation 攻防实战(图)
  18. Ubuntu中程序崩溃,杀死进程方法
  19. 内存重叠的拷贝--memmove
  20. Android 华为手机10.1 启动service Service starting has been prevented by iaware or trustsbase **

热门文章

  1. qlabel 显示图片后大小不变_图形编程:QT使用scrollarea显示图片的解决方案
  2. MySQL迁移安装_mysql数据库安装路径迁移
  3. c语言学习进阶-C语言程序实现矩阵乘法
  4. 使用TensorFlow.js进行人脸触摸检测第2部分:使用BodyPix
  5. Angular和.NET Core Web API入门应用程序
  6. Fedora 31 及以后版本将不再支持 32 位内核已实锤
  7. kali怎么进入root用户_linux中怎么进入root用户
  8. linux hadoop namenode_HADOOP_HDFS伪分布式安装步骤
  9. idea中实体类右击没有ptg_这些6到飞起的idea插件,你还没用过?
  10. oracle 时间按季度,ORACLE时间字段取年、月、日、季度