原标题:玩转 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 类详细代码如下:
1publicclassUserimplementsSerializable{
2
3privateString name;
4privateInteger age;
5
6publicUser(String name,Integer age){
7this.name = name;
8this.age = age;
9}
10//省掉 getter and setter 办法
11}
关于 过期时刻处理和回来Jedis 线程操作到线程池操作封装到了 JedisCacheServiceSupport 中,详细代码如下:
1publicabstractclassJedisCacheServiceSupport{
2publicstaticfinallongEXPIRE_MILLISECONDS_DEFAULT_LONG = 3* 60* 60* 1000;
3
4publicLong getExpireTime(Long expireTime){
5expireTime = (expireTime == null|| expireTime.longValue <= 0) ? EXPIRE_MILLISECONDS_DEFAULT_LONG : expireTime;
6returnexpireTime;
7}
8
9publicvoidclose(Jedis jedis){
10if(jedis != null){
11jedis.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
2publicclassJedisCacheServiceextendsJedisCacheServiceSupport{
3
4privatestaticLogger logger = LoggerFactory.getLogger(JedisCacheService.class);
5
6
7
8@Autowired
9privateJedisPool jedisPool;
10
11
16publicObject getObject( String key) {
17Jedis jedis = null;
18Object object= null;
19try{
20jedis = jedisPool.getResource;
21byte[] ObjectByteArray = jedis. get(key.getBytes);
22object= unserialize(ObjectByteArray);
23} catch(Exception e){
24e.printStackTrace;
25} finally{
26close(jedis);
27}
28returnobject;
29}
30
31
36publicvoidputObject( String key, Object value) {
37putObject(key, value, null);
38}
39
44publicvoidputObject( String key, Object value, Long expireTime ) {
45Jedis jedis = null;
46try{
47jedis = jedisPool.getResource;
48jedis.psetex(key.getBytes,getExpireTime(expireTime),serialize( value));
49} catch(Exception e){
50e.printStackTrace;
51} finally{
52close(jedis);
53}
54}
55
56
57
62publicstaticbyte[] serialize( Object object) {
63ObjectOutputStream oos = null;
64ByteArrayOutputStream baos = null;
65try{
66baos = newByteArrayOutputStream;
67oos = newObjectOutputStream(baos);
68oos.writeObject( object);
69byte[] bytes = baos.toByteArray;
70returnbytes;
71} catch(Exception e) {
72logger.error(e.getMessage, e);
73} finally{
74IOUtil.closeStream(oos);
75IOUtil.closeStream(baos);
76}
77returnnull;
78}
79
80
85publicstaticObject unserialize( byte[] bytes ) {
86if(bytes == null) returnnull;
87
88ByteArrayInputStream bais = null;
89ObjectInputStream ois = null;
90try{
91bais = newByteArrayInputStream(bytes);
92ois = newObjectInputStream(bais);
93returnois.readObject;
94} catch(Exception e) {
95logger.error(e.getMessage, e);
96} finally{
97IOUtil.closeStream(bais);
98IOUtil.closeStream(ois);
99}
100returnnull;
101}
102}
封闭 输入流和输出流东西类详细代码如下:
1publicclassIOUtil{
2publicstaticvoidcloseStream( InputStream inputStream) {
3if(inputStream != null) {
4try{
5inputStream.close;
6} catch(IOException e) {
7e.printStackTrace;
8}
9
10}
11}
12
13publicstaticvoidcloseStream( OutputStream outputStream) {
14if(outputStream != null) {
15try{
16outputStream.close;
17} catch(IOException e) {
18e.printStackTrace;
19}
20
21}
22}
23}
序列化办法演示
测验 JedisCacheService putObject(将目标放入缓存中)、getObject(从缓存中获取目标),详细代码如下:
1@RunWith(SpringRunner.class)
2@SpringBootTest
3publicclassJedisCacheServiceTest{
4privateLogger logger = LoggerFactory.getLogger(JedisCacheService.class);
5@Autowired
6privateJedisCacheService jedisCacheService;
7
8@Test
9publicvoidputObject{
10User user = newUser( "zhuoqiammingyue", 19);
11jedisCacheService.putObject( "user01",user);
12logger.info( "缓存用户成功!");
13}
14
15@Test
16publicvoidgetObject{
17User user = (User)jedisCacheService.getObject( "user01");
18logger.info( "User name={},age={}",user.getName,user.getAge);
19}
20}
putObject 日志信息:
12020 -02-2622 :08:50.320INFO26748 ---[ main]cn.lijunkui.cache.JedisCacheServiceTest: StartedJedisCacheServiceTestin7 .157seconds( JVMrunningfor9 .357)
22020 -02-2622 :08:51.144INFO26748 ---[ main]cn.lijunkui.cache.JedisCacheService: 缓存用户成功!
getObject 日志信息:
12020- 02- 2622: 09: 57.492INFO 9612--- [ main] cn.lijunkui.cache.JedisCacheServiceTest : Started JedisCacheServiceTest in7.07seconds (JVM running for8.902)
22020- 02- 2622: 09: 58.143INFO 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
2publicclassJedisJsonCacheServiceextendsJedisCacheServiceSupport{
3
4privatestaticLogger logger = LoggerFactory.getLogger(JedisJsonCacheService.class);
5
6@Autowired
7privateJedisPool jedisPool;
8
9
15publicObject getObject(String key, Classclazz) {
16Jedis jedis = null;
17Object object = null;
18try{
19jedis = jedisPool.getResource;
20String objectJson = jedis.get(key);
21object = toObjce(objectJson,clazz);
22} catch( Exceptione){
23e.printStackTrace;
24} finally{
25close(jedis);
26}
27returnobject;
28}
29
30
35publicvoid putObject(String key, Object value) {
36putObject(key, value, null);
37}
38
39
45publicvoid putObject(String key, Object value, Long expireTime) {
46Jedis jedis = null;
47try{
48jedis = jedisPool.getResource;
49jedis.psetex(key,getExpireTime(expireTime),toJson(value));
50} catch( Exceptione){
51e.printStackTrace;
52} finally{
53close(jedis);
54}
55}
56
57
58
59
64privateString toJson(Object value) {
65Gson gson = newGson;
66returngson.toJson(value);
67}
68
69
75privateObject toObjce(String json, Classclazz) {
76Gson gson = newGson;
77returngson.fromJson(json,clazz);
78}
79}
序列化办法演示
测验 JedisJsonCacheServiceTest putObject(将目标放入缓存中)、getObject(从缓存中获取目标),详细代码如下:
1@RunWith(SpringRunner.class)
2@SpringBootTest
3publicclassJedisJsonCacheServiceTest{
4
5privateLogger logger = LoggerFactory.getLogger(JedisJsonCacheServiceTest.class);
6@Autowired
7privateJedisJsonCacheService jedisJsonCacheService;
8
9@Test
10publicvoidputObject{
11User user = newUser( "zhuoqiammingyue2", 20);
12jedisJsonCacheService.putObject( "user02",user);
13logger.info( "缓存用户成功!");
14}
15
16@Test
17publicvoidgetObject{
18User user = (User)jedisJsonCacheService.getObject( "user02",User.class);
19logger.info( "User name={},age={}",user.getName,user.getAge);
20}
21}
putObject 日志信息:
12020 -02-2707 :57:16.184INFO3692 ---[ main]c.l.cache.JedisJsonCacheServiceTest: StartedJedisJsonCacheServiceTestin7 .92seconds( JVMrunningfor10 .786)
22020 -02-2707 :57:16.852INFO3692 ---[ main]c.l.cache.JedisJsonCacheServiceTest: 缓存用户成功!
getObject 日志信息:
12020- 02- 2707: 57: 56.359INFO 27624--- [ main] c.l.cache.JedisJsonCacheServiceTest : Started JedisJsonCacheServiceTest in7.364seconds (JVM running for9.256)
22020- 02- 2707: 57: 56.824INFO 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
责任编辑: