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());
	}
}
原文地址:https://www.cnblogs.com/hthuang/p/7930551.html