springboot2.x其中使用的是Lettuce。 

pom文件:

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

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <!-- redis依赖commons-pool-->
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
        </dependency>

application配置文件:

server:
  port: 1015
spring:
  redis:
    #SINGLE: 单机 CLUSTER:集群 SENTINEL: 哨兵
    redis-model: ${REDIS_MODEL:CLUSTER}  //可配置

    //用于单机
    host: ${REDIS_HOST}
    database: ${REDIS_DATABASE}
    password: ${REDIS_PASSWORD}
    port: ${REDIS_PORT}

    cluster:
      nodes: ${REDIS_CLUSTER_NODES}
      max-redirects: ${REDIS_CLUSTER_MAX_REDIRECTS}

    sentinel:
      master: ${REDIS_SENTINEL_MASTER}
      nodes: ${REDIS_SENTINEL_NODES}

    lettuce:
      pool:
        max-active: 1000
        max-idle: 10
        max-wait: -1
        min-idle: 3

redis配置类:

package com.fii.eodc.intellect.config;

import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisNode;
import org.springframework.data.redis.connection.RedisSentinelConfiguration;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.HashSet;
import java.util.Set;

/**
 * @author aric
 * @create 2021-07-13-17:38
 * @fun
 */
@Configuration
public class RedisConfig {

//单节点简单版
//    @Bean
//    public RedisTemplate<String, String> redisTemplate(LettuceConnectionFactory factory){
//        RedisTemplate<String, String> template = new RedisTemplate<>();
//        template.setConnectionFactory(factory);
//        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
//        ObjectMapper objectMapper = new ObjectMapper();
//        objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//        objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//        jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
//        StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
//        //key采用String的序列化方式
//        template.setKeySerializer(stringRedisSerializer);
//        //value采用jackson序列化方式
//        template.setValueSerializer(jackson2JsonRedisSerializer);
//        //hash的key采用String的序列化方式
//        template.setHashKeySerializer(stringRedisSerializer);
//        //hash的value采用String的序列化方式
//        template.setHashValueSerializer(jackson2JsonRedisSerializer);
//        template.afterPropertiesSet();
//        return template;
//    }


//可配置多节点版本
    //节点选择
    @Value("${spring.redis.redis-model:}")
    private String redisModel;

    //单机节点配置
    @Value("${spring.redis.host:}")
    private String host;
    @Value("${spring.redis.database:}")
    private String database;
    @Value("${spring.redis.password:}")
    private String password;
    @Value("${spring.redis.port:}")
    private String port;

    //哨兵节点配置
    @Value("${spring.redis.sentinel.master:}")
    private String master;
    @Value("${spring.redis.sentinel.nodes:}")
    private String sentinelNodes;

    //集群节点配置
    @Value("${spring.redis.cluster.max-redirects:}")
    private String maxRedirects;
    @Value("${spring.redis.cluster.nodes:}")
    private String clusterNodes;

    //连接池配置
    @Value("${spring.redis.lettuce.pool.max-active:}")
    private Integer maxActive;
    @Value("${spring.redis.lettuce.pool.min-idle:}")
    private Integer minIdle;
    @Value("${spring.redis.lettuce.pool.max-idle:}")
    private Integer maxIdle;
    @Value("${spring.redis.lettuce.pool.max-wait:}")
    private Long maxWaitMillis;

    @Bean
    LettuceConnectionFactory lettuceConnectionFactory() {
         // 连接池配置
        GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
        poolConfig.setMaxIdle(maxIdle == null ? 8 : maxIdle);
        poolConfig.setMinIdle(minIdle == null ? 1 : minIdle);
        poolConfig.setMaxWaitMillis(maxWaitMillis == null ? 5000L : maxWaitMillis);
        LettucePoolingClientConfiguration lettucePoolingClientConfiguration = LettucePoolingClientConfiguration.builder()
                .poolConfig(poolConfig)
                .build();
        if (redisModel.equalsIgnoreCase("SINGLE")) {
            // 单机redis
            RedisStandaloneConfiguration redisConfig = new RedisStandaloneConfiguration();
            redisConfig.setHostName(host == null || "".equals(host) ? "localhost" : host);
            redisConfig.setPort(Integer.valueOf(host == null || "".equals(host) ? "6379" : port));
            redisConfig.setDatabase(Integer.valueOf(database));
            if (password != null && !"".equals(password)) {
                redisConfig.setPassword(RedisPassword.of(password));
            }
            return new LettuceConnectionFactory(redisConfig, lettucePoolingClientConfiguration);
        } else if (redisModel.equalsIgnoreCase("SENTINEL")) {
            //哨兵redis
            RedisSentinelConfiguration redisConfig = new RedisSentinelConfiguration();
            redisConfig.sentinel(host, Integer.valueOf(port));
            redisConfig.setMaster(master);
            redisConfig.setPassword(RedisPassword.of(password));
            if (sentinelNodes != null) {
                List<RedisNode> redisNodeList = Arrays.stream(sentinelNodes.split(",")).map(item -> {
                    String[] arr = item.split(":");
                    return new RedisNode(arr[0], Integer.parseInt(arr[1]));
                }).collect(Collectors.toList());
                redisConfig.setSentinels(redisNodeList);
            }
            return new LettuceConnectionFactory(redisConfig, lettucePoolingClientConfiguration);
        } else {
            // 集群redis
            RedisClusterConfiguration redisConfig = new RedisClusterConfiguration();
            Set<RedisNode> nodeses = new HashSet<>();
            //-分割方式
//            String[] hostses = clusterNodes.split("-");
//            for (String h : hostses) {
//                h = h.replaceAll("\\s", "").replaceAll("\n", "");
//                if (!"".equals(h)) {
//                    String host = h.split(":")[0];
//                    int port = Integer.valueOf(h.split(":")[1]);
//                    nodeses.add(new RedisNode(host, port));
//                }
//            }
            List<String> clusterList = Arrays.asList(clusterNodes.split(","));
            for(String sen : clusterList) {
                String[] arr = sen.split(":");
                nodeses.add(new RedisNode(arr[0],Integer.parseInt(arr[1])));
            }
            redisConfig.setClusterNodes(nodeses);
            //跨集群执行命令时要遵循的最大重定向数量
            redisConfig.setMaxRedirects(Integer.valueOf(maxRedirects));
            redisConfig.setPassword(RedisPassword.of(password));
            return new LettuceConnectionFactory(redisConfig, lettucePoolingClientConfiguration);
        }
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate(LettuceConnectionFactory lettuceConnectionFactory) {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(lettuceConnectionFactory);
        //序列化类
        MyRedisSerializer myRedisSerializer = new MyRedisSerializer();
        //key序列化方式
        template.setKeySerializer(myRedisSerializer);
        //value序列化
        template.setValueSerializer(myRedisSerializer);
        //value hashmap序列化
        template.setHashValueSerializer(myRedisSerializer);
        return template;
    }

    static class MyRedisSerializer implements RedisSerializer<Object> {

        @Override
        public byte[] serialize(Object o) throws SerializationException {
            return serializeObj(o);
        }

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

        /**
         * 序列化
         *
         * @param object
         * @return
         */
        private static byte[] serializeObj(Object object) {
            ObjectOutputStream oos = null;
            ByteArrayOutputStream baos = null;
            try {
                baos = new ByteArrayOutputStream();
                oos = new ObjectOutputStream(baos);
                oos.writeObject(object);
                byte[] bytes = baos.toByteArray();
                return bytes;
            } catch (Exception e) {
                throw new RuntimeException("序列化失败!", e);
            }
        }

        /**
         * 反序列化
         *
         * @param bytes
         * @return
         */
        private static Object deserializeObj(byte[] bytes) {
            if (bytes == null) {
                return null;
            }
            ByteArrayInputStream bais = null;
            try {
                bais = new ByteArrayInputStream(bytes);
                ObjectInputStream ois = new ObjectInputStream(bais);
                return ois.readObject();
            } catch (Exception e) {
                throw new RuntimeException("反序列化失败!", e);
            }
        }
    }
}

测试用例:

注入:

@Autowired
private RedisTemplate<String, Object> redisTemplate;
添加:

redisTemplate.opsForValue().set(key, value);
添加,设置过期时间:

redisTemplate.opsForValue().set(key, obj, expireTime, TimeUnit.SECONDS);
获取:

Object o = redisTemplate.opsForValue().get(key);
删除:

redisTemplate.delete(key);

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐