玩转 SpringBoot2.x 之缓存对象

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

作者 | 桌前明月

来源 | CSDN博客

头图 | 付费下载自视觉中国

出品 | CSDN(ID:CSDNnews)

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

前言

提到Redis 大部分的人首先想到的可能就是缓存,那么在 Java 项目中如何把对象缓存起来呢?这就是本文接下来要介绍的内容:缓存对象。本文通过SpringBoot 项目带你快速了解通过Jedis 把对象缓存到Redis中。

阅读本文需要你了解如何搭建 SpringBoot 项目即可,另外需要了解的是本文SpringBoot 版本是 2.1.0.RELEASE。关于SpringBoot 集成 Jedis 请参考:玩转 SpringBoot 2.x 之 快速集成 Jedis客户端(普通版)

接下来就让我们开始具体的代码案例介绍吧!

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

代码案例

演示通过将下面的 User 类创建的对象缓存到 Redis 中,具体有2种方式:序列化、Json。User 类具体代码如下:

<code> 1public class User implements Serializable {
2
3 private String name;
4 private Integer age;
5
6 public User(String name,Integer age){
7 this.name = name;
8 this.age = age;
9 }
10 //省略 getter and setter 方法
11}
/<code>

关于 过期时间处理和返回Jedis 线程操作到线程池操作封装到了 JedisCacheServiceSupport 中,具体代码如下:

<code> 1public abstract class JedisCacheServiceSupport {
2 public static final long EXPIRE_MILLISECONDS_DEFAULT_LONG = 3*60*60*1000;
3
4 public Long getExpireTime(Long expireTime) {
5 expireTime = (expireTime == || expireTime.longValue <= 0) ? EXPIRE_MILLISECONDS_DEFAULT_LONG : expireTime;
6 return expireTime;
7 }
8
9 public void close(Jedis jedis){
10 if(jedis != ){
11 jedis.close;
12 }
13 }
14}
/<code>
玩转 SpringBoot2.x 之缓存对象 | 原力计划

序列化方式

序列化的方式通过现将对象转换成二进制的流(序列化)后保存到 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对象。

通过序列化方式保存和获取对象具体代码如下:

<code> 1@Service
2public class JedisCacheService extends JedisCacheServiceSupport {
3

4 private static Logger logger = LoggerFactory.getLogger(JedisCacheService.class);
5
6
7
8 @Autowired
9 private JedisPool jedisPool;
10
11 /**
12 * 获取缓存中的对象
13 * @param key
14 * @return
15 */
16 public Object getObject(String key) {
17 Jedis jedis = ;
18 Object object = ;
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 }
30
31 /**
32 * 将对象缓存到Redis中,设置默认过期时间
33 * @param key
34 * @param value
35 */
36 public void putObject(String key, Object value) {
37 putObject(key,value,);
38 }
39 /**
40 * 将对象缓存到Redis中,自定义认过期时间
41 * @param key
42 * @param value
43 */
44 public void putObject(String key, Object value, Long expireTime) {
45 Jedis jedis = ;
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 }
55
56
57 /**
58 * 序列化
59 * @param object
60 * @return
61 */
62 public static byte serialize(Object object) {
63 ObjectOutputStream oos = ;
64 ByteArrayOutputStream baos = ;
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 ;
78 }
79
80 /**
81 * 反序列化
82 * @param bytes
83 * @return
84 */
85 public static Object unserialize(byte[] bytes) {
86 if (bytes == ) return ;
87
88 ByteArrayInputStream bais = ;
89 ObjectInputStream ois = ;
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 ;
101 }
102}
/<code>

关闭 输入流和输出流工具类具体代码如下:

<code> 1public class IOUtil {
2 public static void closeStream(InputStream inputStream) {
3 if (inputStream != ) {
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 != ) {
15 try {
16 outputStream.close;
17 } catch (IOException e) {
18 e.printStackTrace;
19 }
20
21 }
22 }
23}
/<code>
玩转 SpringBoot2.x 之缓存对象 | 原力计划

序列化方式演示

测试 JedisCacheService putObject(将对象放入缓存中)、getObject(从缓存中获取对象),具体代码如下:

<code> 1@RunWith(SpringRunner.class)
2@SpringBootTest
3public class JedisCacheServiceTest {
4 private Logger logger = LoggerFactory.getLogger(JedisCacheService.class);
5 @Autowired
6 private JedisCacheService jedisCacheService;
7
8 @Test
9 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}
/<code>

putObject 日志信息:

<code>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 : 缓存用户成功!
/<code>

getObject 日志信息:

<code>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
/<code>
玩转 SpringBoot2.x 之缓存对象 | 原力计划

Json 方式

Json 的方式是将对象转换成可阅读的Json 串后保存到 Redis 中,然后通过key 获取到Json 串,在把Json 串成对象。对象转成成Json串是通过谷歌的Gson 完成的,所以需要引入Gson的依赖,具体依赖代码如下:

<code>1<dependency>
2 <groupid>com.google.code.gson/<groupid>
3 <artifactid>gson/<artifactid>
4 <version>2.8.5/<version>
5/<dependency>
/<code>

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 classOfT) 将Json串转换成User对象。

通过Json 方式保存和获取对象具体代码如下:

<code> 1@Service
2public class JedisJsonCacheService extends JedisCacheServiceSupport {
3
4 private static Logger logger = LoggerFactory.getLogger(JedisJsonCacheService.class);
5
6 @Autowired
7 private JedisPool jedisPool;
8
9 /**
10 * 获取缓存中的对象

11 * @param key
12 * @param clazz
13 * @return
14 */
15 public Object getObject(String key,Class clazz) {
16 Jedis jedis = ;
17 Object object = ;
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,);
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 = ;
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}
/<code>
玩转 SpringBoot2.x 之缓存对象 | 原力计划

序列化方式演示

测试 JedisJsonCacheServiceTest putObject(将对象放入缓存中)、getObject(从缓存中获取对象),具体代码如下:

<code> 1@RunWith(SpringRunner.class)
2@SpringBootTest
3public class JedisJsonCacheServiceTest {
4
5 private Logger logger = LoggerFactory.getLogger(JedisJsonCacheServiceTest.class);
6 @Autowired
7 private JedisJsonCacheService jedisJsonCacheService;
8
9 @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}
/<code>

putObject 日志信息:

<code>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 : 缓存用户成功!
/<code>

getObject 日志信息:

<code>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
/<code>
玩转 SpringBoot2.x 之缓存对象 | 原力计划

小结

序列化和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


分享到:


相關文章: