SpringBoot整合Redis实现序列化存储Java对象

看了不少文章,往Redis里存对象基本上不外乎两种:将对象转化成Json,然后取出来之后在反序列化,或者将对象转成byte[]。而如果你使用SpringBoot的话,使用Spring-data-redis可能会更加简便。

首先我们使用maven搭建Spring Boot项目,引入Spring data redis的依赖。

 
     org.springframework.boot
     spring-boot-starter-data-redis
 

然后在application.yml(我喜欢使用这种配置)里配置redis

spring:
  redis:
    host: localhost
写一个测试类,注意一定要实现序列化接口

import java.io.Serializable;
 
public class Test implements Serializable {
    private String id;
    private String name;
    private int age;
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
然后为了简便测试,写一个Controller类。如下:

import com.cxy.animecl.main.pojo.test.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
@RequestMapping(value = "/redis")
@RestController
public class RedisController {
    @Autowired
    private RedisTemplate redisTemplate;
    @RequestMapping(value = "/set")
    public String set(){
        Test test = new Test();
        test.setId("1");
        test.setAge(20);
        test.setName("张三");
        redisTemplate.opsForValue().set("1", test);
        return "OK";
    }
 
    @RequestMapping(value = "/get")
    public Test get(){
        return (Test)redisTemplate.opsForValue().get("1");
    }
}
这里我们直接Autowire注入Spring给我们提供的RedisTemplate类,(其实还提供了另外一种StringRedisTemplate,这个专门用来操作字符串)注意泛型都写Object,否则会报错。

然后我们用浏览器访问地址进行操作,经过测试没有问题,如图:

 

SpringBoot整合Redis实现序列化存储Java对象_第1张图片

怎么样,是不是很简单?通过Spring封装的Redis可以很简单的将Java对象存入Redis中,而取出来之后也只需要强转一下就OK。那么我们看一下redis里到底存的是什么?

127.0.0.1:6379> keys *
1) "\xac\xed\x00\x05t\x00\x011"
127.0.0.1:6379> get "\xac\xed\x00\x05t\x00\x011"
"\xac\xed\x00\x05sr\x00#com.cxy.animecl.main.pojo.test.Test\xb6\xe2\xd8.\x93\xc3R\x8d\x02\x00\x03I\x00\x03ageL\x00\x02idt\x00\x12Ljava/lang/String;L\x00\x04nameq\x00~\x00\x01xp\x00\x00\x00\x14t\x00\x011t\x00\x06\xe5\xbc\xa0\xe4\xb8\x89"
127.0.0.1:6379>

源码分析

 

SpringBoot整合Redis实现序列化存储Java对象_第2张图片

 

  • 以上是 RedisAutoConfiguration 类中的源码片段,可以看出 SpringBoot 对 Redis 做自动化配置的时候,在容器中注入了 redisTemplate 和 stringRedisTemplate
  • 其中,RedisTemplate 表示,key 的类型为 Object,value 的类型为 Object,但是我们往往需要的是 RedisTemplate,这就需要我们重新注入一个 RedisTemplate 的 Bean,它的泛型为 RedisTemplate,并设置 key,value 的序列化方式
  • 看到这个@ConditionalOnMissingBean注解后,就知道如果Spring容器中有了RedisTemplate对象了,这个自动配置的RedisTemplate不会实例化。因此我们可以直接自己写个配置类,配置RedisTemplate。

三、注入RedisTemplate

  • 1、引入依赖


    org.springframework.boot
    spring-boot-starter-data-redis

以上引入了 redis 的依赖,其余依赖请自行添加

  • 2、Redis 连接信息
spring:
  # Redis配置
  redis:
    host: 127.0.0.1
    port: 6379
    database: 10
    jedis:
      pool:
        # 连接池最大连接数(使用负值表示没有限制)
        max-active: 50
        # 连接池最大阻塞等待时间(使用负值表示没有限制)
        max-wait: 3000ms
        # 连接池中的最大空闲连接数
        max-idle: 20
        # 连接池中的最小空闲连接数
        min-idle: 5
    # 连接超时时间(毫秒)
    timeout: 5000ms
  • 3、Redis 核心配置类

Redis 的核心配置我们放在 RedisConfig.java 文件中

package com.zyxx.redistest.common;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

/**
 * @ClassName RedisConfig
 * @Description
 * @Author Lizhou
 * @Date 2020-10-22 9:48:48
 **/

@Configuration
public class RedisConfig {

    /**
     * RedisTemplate配置
     */
    @Bean
    public RedisTemplate redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        // 设置序列化
        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);
        // 配置redisTemplate
        RedisTemplate redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(lettuceConnectionFactory);
        RedisSerializer stringSerializer = new StringRedisSerializer();
        // key序列化
        redisTemplate.setKeySerializer(stringSerializer);
        // value序列化
        redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
        // Hash key序列化
        redisTemplate.setHashKeySerializer(stringSerializer);
        // Hash value序列化
        redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
} 
  

我们注入了一个名称为 redisTemplate,类型为 RedisTemplate 的 Bean,key 采用 StringRedisSerializer 序列化方式,value 采用 Jackson2JsonRedisSerializer 序列化方式

  • 4、Redis工具类

我们将对 Redis 进行的一系列操作放在 RedisUtils.java 文件中

package com.zyxx.redistest.common;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;

/**
 * @ClassName RedisUtils
 * @Description
 * @Author Lizhou
 * @Date 2020-10-22 10:10:10
 **/
@Slf4j
@Component
public class RedisUtils {

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 根据key读取数据
     */
    public Object get(final String key) {
        if (StringUtils.isBlank(key)) {
            return null;
        }
        try {
            return redisTemplate.opsForValue().get(key);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 写入数据
     */
    public boolean set(final String key, Object value) {
        if (StringUtils.isBlank(key)) {
            return false;
        }
        try {
            redisTemplate.opsForValue().set(key, value);
            log.info("存入redis成功,key:{},value:{}", key, value);
            return true;
        } catch (Exception e) {
            log.error("存入redis失败,key:{},value:{}", key, value);
            e.printStackTrace();
        }
        return false;
    }
}

我们写入了 get,set 两个方法用于测试

四、测试

  • 1、创建 Java 实体类 UserInfo
package com.zyxx.redistest.common;

import lombok.Data;

import java.io.Serializable;
import java.util.Date;

/**
 * @ClassName UserInfo
 * @Description
 * @Author Lizhou
 * @Date 2020-10-22 10:12:12
 **/
@Data
public class UserInfo implements Serializable {
    /**
     * id
     */
    private Integer id;
    /**
     * 姓名
     */
    private String name;
    /**
     * 创建时间
     */
    private Date createTime;
}
  • 2、测试用例
package com.zyxx.redistest;

import com.zyxx.redistest.common.RedisUtils;
import com.zyxx.redistest.common.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Date;

@SpringBootTest
class RedisTestApplicationTests {

    @Autowired
    private RedisUtils redisUtil;

    @Test
    void contextLoads() {
        UserInfo userInfo = new UserInfo();
        userInfo.setId(1);
        userInfo.setName("jack");
        userInfo.setCreateTime(new Date());
        // 放入redis
        redisUtil.set("user", userInfo);
        // 从redis中获取
		System.out.println("获取到数据:" + redisUtil.get("user"));
    }
}

我们向 Redis 中存入了一个 key 为 ”user“,value 为 UserInfo 对象的数据,然后再根据 key 获取该数据

  • 3、测试结果


可以看出,我们往 Redis 中成功存入 Java 对象数据,并成功获取到了该对象

你可能感兴趣的:(redis)