Redis在Spring Boot中的应用

最近项目中用到Redis,上网查了很多示例,发现或多或少都有问题。踩过很多坑,终于在Spring Boot中成功实现了Redis存储。记录如下,方便别人,也方便自己。

Redis(REmote DIctionary Server) 是一个由Salvatore Sanfilippo写的key-value存储系统。Redis是一个开源的使用ANSI C语言编写、遵守BSD协议、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。它通常被称为数据结构服务器,因为值(value)可以是 字符串(String), 哈希(Map), 列表(list), 集合(sets) 和 有序集合(sorted sets)等类型。

Redis安装

至于在服务器上如何搭建Redis存储系统,本文就不在赘述,网上相关教程很多,请自行Google。如果要实现Redis可远程连接,需要注意一下几点:

  1. 配置文件redis.conf设置Redis可远程访问
  2. 设置登录密码
  3. 设置Redis可在后台运行
  4. 开启防火墙端口,Redis默认端口为6379
  5. 建议设置为开机自启动

Spring Boot中Redis应用

1. 引入依赖

pom.xml文件中依赖如下

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

2. 配置文件

可以利用配置文件进行设置,也可以直接通过注释配置。配置文件application.yml如下:

spring:
  # REDIS (RedisProperties)
  redis:
    # Redis服务器地址
    host: 192.168.1.197
    # Redis服务器连接端口
    port: 6379
    pool:
      # 连接池中的最大空闲连接
      max-idle: 8
      # 连接池中的最小空闲连接
      min-idle: 0
      # 连接池最大连接数(使用负值表示没有限制)
      max-active: 8
      # 连接池最大阻塞等待时间(使用负值表示没有限制)
      max-wait: -1
    # 连接超时时间(毫秒)
    timeout: 0
    # Redis数据库索引(默认为0)
    database: 0
    # Redis服务器连接密码(默认为空)
    password: your-password

3. 定义RedisTemplate

package com.ygingko.utest.config;

import com.ygingko.utest.config.redis.RedisObjectSerializer;
import com.ygingko.utest.entity.dto.UserDTO;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;

@Configuration
@PropertySource("classpath:application.yml")
public class RedisConfig {

    @Value("${spring.redis.host}")
    private String host;

    @Value("${spring.redis.port}")
    private int port;

    @Value("${spring.redis.password}")
    private String password;

    @Value("${spring.redis.database}")
    private int database;

    @Value("${spring.redis.timeout}")
    private int timeout;

    @Value("${spring.redis.pool.max-active}")
    private int maxActive;

    @Value("${spring.redis.pool.max-idle}")
    private int maxIdle;

    @Value("${spring.redis.pool.min-idle}")
    private int minIdle;

    @Value("${spring.redis.pool.max-wait}")
    private long maxWait;

    @Bean
    JedisConnectionFactory jedisConnectionFactory() {
        JedisConnectionFactory factory = new JedisConnectionFactory();
        factory.setHostName(host);
        factory.setPort(port);
        factory.setPassword(password);
        factory.setDatabase(database);
        factory.setTimeout(timeout);

        JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
        jedisPoolConfig.setMaxTotal(maxActive);
        jedisPoolConfig.setMaxIdle(maxIdle);
        jedisPoolConfig.setMinIdle(minIdle);
        jedisPoolConfig.setMaxWaitMillis(maxWait);

        factory.setPoolConfig(jedisPoolConfig);

        return factory;
    }

    @Bean
    public RedisTemplate<String, UserDTO> redisTemplate() {
        RedisTemplate<String, UserDTO> template = new RedisTemplate<>();
        template.setConnectionFactory(jedisConnectionFactory());
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new RedisObjectSerializer());
        return template;
    }
}

4. 实现RedisSerializer接口

package com.ygingko.utest.config.redis;

import org.springframework.core.convert.converter.Converter;
import org.springframework.core.serializer.support.DeserializingConverter;
import org.springframework.core.serializer.support.SerializingConverter;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

public class RedisObjectSerializer implements RedisSerializer {

    private Converter<Object, byte[]> serializer = new SerializingConverter();
    private Converter<byte[], Object> deserializer = new DeserializingConverter();

    private static final byte[] EMPTY_ARRAY = new byte[0];

    @Override
    public byte[] serialize(Object o) throws SerializationException {
        if (o == null) {
            return EMPTY_ARRAY;
        }

        try {
            return serializer.convert(o);
        } catch (Exception e) {
            return EMPTY_ARRAY;
        }
    }

    @Override
    public Object deserialize(byte[] bytes) throws SerializationException {
        if (isEmpty(bytes)) {
            return null;
        }

        try {
            return deserializer.convert(bytes);
        } catch (Exception e) {
            throw new SerializationException("Cannot deserialize ", e);
        }
    }

    private boolean isEmpty(byte[] data) {
        return (data == null || data.length == 0);
    }
}

5. 存数对象

存储对象必须实现Serializable接口,有固定的serialVersionUID。如下:

package com.ygingko.utest.entity.dto;

import com.alibaba.fastjson.JSON;

import java.io.Serializable;

public class UserDTO implements Serializable {
    private static final long serialVersionUID = 4044555734385804034L;

    private Integer uid;
    private String name;
    private String password;
    private Integer level;

    public Integer getUid() {
        return uid;
    }

    public void setUid(Integer uid) {
        this.uid = uid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Integer getLevel() {
        return level;
    }

    public void setLevel(Integer level) {
        this.level = level;
    }

    @Override
    public String toString() {
        return JSON.toJSONString(this);
    }
}

6. 应用示例

package com.ygingko.utest;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import redis.clients.jedis.Jedis;

import java.util.ArrayList;
import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UtestApplicationTests {

    @Autowired
    private RedisTemplate<String, UserDTO> redisTemplate;

    @Test
    public void testRedis() throws Exception {
        UserDTO userBean = new UserDTO();
        userBean.setUid(1001);
        userBean.setName("huang");
        userBean.setLevel(1);
        redisTemplate.opsForValue().set("token", userBean);
        System.out.println(redisTemplate.opsForValue().get("token"));
    }

    @Test
    public void contextLoads() {

        Jedis jedis = new Jedis("192.168.1.197", 6379);
        System.out.println("****************" + jedis.ping());
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小樱的经验随笔

【BZOJ】初级水题列表——献给那些想要进军BZOJ的OIers(自用,怕荒废了最后的六月考试月,刷刷水题,水水更健康)

BZOJ初级水题列表——献给那些想要进军BZOJ的OIers 代码长度解释一切! 注:以下代码描述均为C++ RunID User Problem Res...

4029
来自专栏24k

spring boot2.0.0 redis序列化解决方案

1594
来自专栏向前进

【笔记】nodejs读取JSON,数组转树

const fs = require('fs'); // --------------- 读取源文件 --------------- const origin...

2334
来自专栏Guangdong Qi

iOS 计算NSString宽高与计算NSAttributedString的宽高

1833
来自专栏刘晓杰

RN实现头部NavBar

3437
来自专栏向治洪

React Native之StyleSheet样式表

概述 在React Native中,StyleSheet是实现了类似Web中CSS样式表的功能。最简单的使用如下,先定一个StyleSheet的样式表,然后在V...

1737
来自专栏菩提树下的杨过

spring-boot 速成(12) - 如何注入多个redis StringRedisTemplate

默认情况下,spring-boot的redis自动配置,只能注册一个StringRedisTemplate实例,如果希望注入多个,比如:1个读写database...

46410
来自专栏lgp20151222

解决Spring Boot 使用RedisTemplate 存储键值出现乱码 \xac\xed\x00\x05t\x00

spring-data-redis的RedisTemplate<K, V>模板类在操作redis时默认使用JdkSerializationRedisSerial...

2001
来自专栏Pulsar-V

MSP430F5529LP IIC与OLED的HELLOWRLD

简单理解下什么是IIC I2C(Inter-Integrated Circuit BUS) 集成电路总线,该总线由NXP(原PHILIPS)公司设计,多用于主...

3677
来自专栏菩提树下的杨过

spring cloud 学习(3) - feign入门

默认情况下,spring-boot的redis自动配置,只能注册一个StringRedisTemplate实例,如果希望注入多个,比如:1个读写database...

1828

扫码关注云+社区