玩转 SpringBoot2.x 之缓存对象 | 原力计划
作者 |桌前明月来源 |CSDN博客头图 | 付费下载自视觉中国出品 | CSDN(ID:CSDNnews)前言提到Redis 大部分的人首先想到的...
作者 | 桌前明月
来源 | 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 {
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}
关于 过期时间处理和返回Jedis 线程操作到线程池操作封装到了 JedisCacheServiceSupport 中,具体代码如下:
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 == null || expireTime.longValue() <= 0) ? EXPIRE_MILLISECONDS_DEFAULT_LONG : expireTime;
6 return expireTime;
7 }
8
9 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@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 = 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 }
30
31 /**
32 * 将对象缓存到Redis中,设置默认过期时间
33 * @param key
34 * @param value
35 */
36 public void putObject(String key, Object value) {
37 putObject(key,value,null);
38 }
39 /**
40 * 将对象缓存到Redis中,自定义认过期时间
41 * @param key
42 * @param value
43 */
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 }
55
56
57 /**
58 * 序列化
59 * @param object
60 * @return
61 */
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 }
79
80 /**
81 * 反序列化
82 * @param bytes
83 * @return
84 */
85 public static Object unserialize(byte[] bytes) {
86 if (bytes == null) return null;
87
88 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@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}
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@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 = 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@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}
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 发布 | 极客头条
☞云原生的漏洞与威胁有哪些?云原生安全性如何?这里有你想知道的一切!
☞编程小白模拟简易比特币系统,手把手带你写一波!(附代码) | 博文精选
你点的每一个在看,我认真当成了喜欢
更多推荐
所有评论(0)