SpringBoot2.X使用Lettuce设置多个RedisTemplate实例


最近公司产品需求,需要使用同一个redis数据库服务使用不同的序列化方式的redisTemplate对缓存数据库进行读写操作,
目前大部分网上的文章在实作Redis分流时,都是以Jedis为样例,但SpringBoot在2.x版本之后已经将Redis库替换成Lettuce了
之前我写过一篇文章就是 SpringBoot2.x Redis多数据源配置(Vavr函数式编程方式实现)
这篇文章是我使用Vavr函数式编程方式实现进行实现的,接下来我将使用一种更简单的方式进行操作
当然在进行实现案例之前我们还是要基于springboot基础的redis库包还是要引入进来的

项目pom配置

使用Spring Boot集成Redis,只需要将spring-boot-starter-data-rediscommons-pool2加到依赖即可

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

配置文件

spring.redis开头的都是Spring Boot自动注入需要加载的配置

spring:
  redis:
    database: 0
    host: localhost
    port: 6379
    password:
    timeout: 60000
    lettuce:
      pool:
        max-active: 8 # 连接池最大连接数(使用负值表示没有限制) 默认 8
        max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
        max-idle: 8 # 连接池中的最大空闲连接 默认 8
        min-idle: 0 # 连接池中的最小空闲连接 默认 0
  redis-db-2:
    database: 2
    host: 127.0.0.1
    port: 6379
    password:
    timeout: 60000
    lettuce:
      pool:
        max-active: 8
        max-wait: 8
        max-idle: 8
        min-idle: 0

RedisConfigure

package com.xiaozhangge.redis.configure;

import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.vavr.Tuple;
import io.vavr.Tuple6;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisClientConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
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.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import java.time.Duration;

/**
 * Created by xiaozhangge on 2020-01-10.
 *
 * @Value("${spring.redis-db-2.database}") int database,
 * @Value("${spring.redis-db-2.host}") String host,
 * @Value("${spring.redis-db-2.port}") int port,
 * @Value("${spring.redis-db-2.password}") String password,
 * @Value("${spring.redis-db-2.timeout}") long timeout,
 * @Value("${spring.redis-db-2.lettuce.pool.max-active}") int maxActive,
 * @Value("${spring.redis-db-2.lettuce.pool.max-wait}") int maxWait,
 * @Value("${spring.redis-db-2.lettuce.pool.max-idle}") int maxIdle,
 * @Value("${spring.redis-db-2.lettuce.pool.min-idle}") int minIdle
 */
@EnableCaching
@Configuration
public class RedisConfigure {
  /**
       * string redis Template创建操作
       *
       * @param database  Redis数据库索引
       * @param timeout   连接超时时间(秒)
       * @param maxActive 连接池最大连接数(使用负值表示沒有限制)
       * @param maxWait   连接池最大等待时间(使用负值表示沒有限制)
       * @param maxIdle   连接池中的最大空闲连接
       * @param minIdle   连接池中的最小空闲连接
       * @param host      Redis服务地址
       * @param password  Redis服务密码
       * @param port      Redis服务器连接端口
       */
      @Bean(name = "stringRedisTemplate")
      public StringRedisTemplate stringRedisTemplate(
              @Value("${spring.redis-db-2.database}")
                      int database,
              @Value("${spring.redis-db-2.timeout:5}")
                      long timeout,
              @Value("${spring.redis-db-2.lettuce.pool.max-active}")
                      int maxActive,
              @Value("${spring.redis-db-2.lettuce.pool.max-wait}")
                      int maxWait,
              @Value("${spring.redis-db-2.lettuce.pool.max-idle}")
                      int maxIdle,
              @Value("${spring.redis-db-2.lettuce.pool.min-idle}")
                      int minIdle,
              @Value("${spring.redis-db-2.host}")
                      String host,
              @Value("${spring.redis-db-2.password}")
                      String password,
              @Value("${spring.redis-db-2.port}")
                      int port
      ) {
          // connection config
          RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration();
          configuration.setHostName(host);
          configuration.setPort(port);
          configuration.setPassword(RedisPassword.of(password));
          configuration.setDatabase(database);

          // pool config
          GenericObjectPoolConfig genericObjectPoolConfig = new GenericObjectPoolConfig();
          genericObjectPoolConfig.setMaxTotal(maxActive);
          genericObjectPoolConfig.setMinIdle(minIdle);
          genericObjectPoolConfig.setMaxIdle(maxIdle);
          genericObjectPoolConfig.setMaxWaitMillis(maxWait);

          // create connection factory
          LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder();
          builder.poolConfig(genericObjectPoolConfig);
          builder.commandTimeout(Duration.ofSeconds(timeout));
          LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(
                  configuration, builder.build()
          );
          connectionFactory.afterPropertiesSet();

          // create redis template
          return createStringRedisTemplate(connectionFactory);

      }

      /**
       * 建立StringRedisTemplate
       * 此function不能加 @Bean 否则onnectionFactory 将会一律采用预设值
       */
      private StringRedisTemplate createStringRedisTemplate(
              RedisConnectionFactory redisConnectionFactory
      ) {
          StringRedisTemplate redisTemplate = new StringRedisTemplate();
          redisTemplate.setConnectionFactory(redisConnectionFactory);
          redisTemplate.setKeySerializer(new StringRedisSerializer());
          redisTemplate.setValueSerializer(new StringRedisSerializer());
          return redisTemplate;
      }
}

具体默认的配置大家可以参考开篇讲解的上一篇文章,我这里仅仅介绍了自定义额外的连接信息。

首先是第一个连接配置信息,这个名称是first,代表第一组Redis连接池配置信息,功能名称会影响到后续在使用上的操作,如果想要另外取名的话可以将bean加上名称@Bean(name=”您的名字””)
在这个函数中接收到框架原型建立的RedisConnectionFactory为参数,将该该工厂传到最底下的createRedisTemplate()来建立StringRedisTemplate,所以如果希望建立的是其他RedisTemplate连接模板的话就可以修改createRedisTemplate()
Redis连接池,如此一来要我们开发过程中操作时忘了标注要使用Redis的话,便会采用这默认的连接池,
接着来看第二个功能,在这个功能中可以看到设定档中第二条连接池的参数,前面提到我们只需要修改连接池的地址信息,所以关于pool等相关设定还是抓第一条连接池的,这边就看大家有没有需要自行修改〜
设置完毕第二条连接池的设置后,进行的事情实际上就是自己建立连接工厂,先设置好Config相关对象,然后创建LettuceConnectionFactory对象,最后和第一个功能相同,将工厂引入createRedisTemplate()来生成RedisTemplate连接池
所以实际上我们要做的事情就是,设置定义的连接池就自定义的factory建立RedisTemplate物件来操作,额外的连线就进入设定档后,自己添加factory来生成RedisTemplate连接模板,就是这么简单〜
连接池建立好后就是实际的操作啦,操作方式也很简单,就用@Autowired就好,只是要带名称让Spring Boot知道你要使用的是其中RedisTemplate哪个连接池即可

@Autowired
@Qualifier("first")
StringRedisTemplate firstRedisTemplate;
@Autowired
@Qualifier("stringRedisTemplate")
StringRedisTemplate secondRedisTemplate;

示例代码:https://github.com/xiaomozhang/personal-life-example/tree/master/example-redis


文章作者: 小张哥
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 小张哥 !
评论
 上一篇
Hexo Matery 常见问题及解决 Hexo Matery 常见问题及解决
前言本文章非 Hexo + Matery Theme 教程,详细教程见blinkfox hexo-theme-matery,主要记录一些使用中的问题,希望能帮到进来的同学,避免踩坑。 常见问题1blog检索不生效我本地的情况是这样的,在主页
2021-02-07
下一篇 
Spring Boot 2.x使用mybatis Spring Boot 2.x使用mybatis
orm框架的本质是简化编程中操作数据库的编码,发展到现在基本上就剩两家了,一个是宣称可以不用写一句SQL的hibernate,一个是可以灵活调试动态sql的mybatis,两者各有特点,在企业级系统开发中可以根据需求灵活使用。 使用注解版p
2021-02-01
  目录