我是靠谱客的博主 慈祥大船,最近开发中收集的这篇文章主要介绍自研 spring boot 连接redis并动态切换database 多redisTemplate方法前要自定义RedisProperties自定义StringRedisTemplateBuildRedisConfig类 RedisConfig 配置类application.yml配置文件用法,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

  • 前要

手头有个项目会用到查询redis同数据源不同database的情况,在网上找了一堆方法感觉在多线程高并发下都会有一些问题。由此,自己研究出了此种方法希望能帮助到大家。

话不多说下面贴代码了开始   O(∩_∩)O哈哈~

  • 自定义RedisProperties

自定义redisProperties实现添加dbList项

package com.dong.base.redis.core;

import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;

import java.util.List;

/**
 *  自定义redis 配置类
 * @author 王少东
 */
public class MyRedisProperties extends RedisProperties {
    // 需要操作的db
    private String dbList;

    public String[] getDbList() {
        if (StringUtils.isEmpty(dbList)) {
            return  null;
        }
        String[] list =  dbList.split(",");
        return list;
    }

    public void setDbList(String dbList) {
        this.dbList = dbList;
    }
}
  • 自定义StringRedisTemplate

自定义SringRedisTemplate实现存储待操作的db的redisTemplate列表

package com.dong.base.redis.core;

import io.lettuce.core.resource.ClientResources;
import io.lettuce.core.resource.DefaultClientResources;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.util.Assert;

import java.util.HashMap;
import java.util.Map;

/**
 * 自定义StringRedisTemplate类
 * @author 王少东
 */
@Data
public class MyStringRedisTemplate extends StringRedisTemplate {

    // 需要切换db的StringRedisTemplate 的 map
    private Map<String, StringRedisTemplate> redisTemplateMap = new HashMap();

    // 需要切换db的ClientResources
    private ClientResources dbListClientResources;

    // 需要切换db的MyRedisProperties
    private MyRedisProperties dbListProperties;

    public MyStringRedisTemplate(){

    }
    public MyStringRedisTemplate(MyRedisProperties properties){
        this(properties,DefaultClientResources.create());
    }
    public MyStringRedisTemplate(MyRedisProperties properties, ClientResources clientResources){
        this(properties,clientResources,null);
    }
    public MyStringRedisTemplate(MyRedisProperties properties, ClientResources clientResources,RedisConnectionFactory redisConnectionFactory){
        this.dbListProperties = properties;
        this.dbListClientResources = clientResources;
        if (redisConnectionFactory != null) {
            this.setConnectionFactory(redisConnectionFactory);
        }
        this.buildMoreDbStringRedisTemple();
    }

    /**
     * 获取某个数据库的RedisTemplate
     * @param dbIndex
     * @return
     */
    public StringRedisTemplate getDbStringRedisTemplate(String dbIndex) {
        StringRedisTemplate template = this.redisTemplateMap.get(dbIndex);
        Assert.isTrue(template != null, dbIndex + "库不存在!");
        return template;
    }
    public StringRedisTemplate getDbStringRedisTemplate(int dbIndex) {
        return getDbStringRedisTemplate(String.valueOf(dbIndex));
    }

    // 构建待切换db列表
    private void buildMoreDbStringRedisTemple () {
        if (dbListProperties != null )
        if (this.dbListProperties.getDbList() != null && this.dbListProperties.getDbList().length > 0) {
            for (String db : this.dbListProperties.getDbList()) {
                Assert.isTrue(StringUtils.isNumeric(db), "redis 配置的dblist 必须是数字!");
                // 当默认和默认db一样的时候设置类本身
                if (db.equals(String.valueOf(this.dbListProperties.getDatabase()))) {
                    redisTemplateMap.put(db,this);
                    continue;
                }
                StringRedisTemplate template = new StringRedisTemplate();
                // 构建 LettuceConnectionFactory 连接池
                LettuceConnectionFactory lettuceConnectionFactory = BuildRedisConfig.buildLettuceConnectionFactory(Integer.valueOf(db), dbListClientResources,this.dbListProperties);
                template.setConnectionFactory(lettuceConnectionFactory);
                lettuceConnectionFactory.afterPropertiesSet();
                template.afterPropertiesSet();
                redisTemplateMap.put(db,template);
            }
        }
    }
}
  • BuildRedisConfig类

BuildRedisConfig是一个构建LettuceConnectionFactory的工具类

package com.dong.base.redis.core;

import io.lettuce.core.resource.ClientResources;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;

/**
 * 公共构建redis BuildRedisConfig的类
 * @author 王少东
 */
public class BuildRedisConfig {

    /**
     * 构建LettuceConnectionFactory的方法
     * @param clientResources
     * @param properties
     * @return
     */
    public static LettuceConnectionFactory buildLettuceConnectionFactory(ClientResources clientResources, RedisProperties properties){
       return buildLettuceConnectionFactory(-1,clientResources, properties );
    }

    /**
     * 构建LettuceConnectionFactory的方法
     * @param clientResources
     * @param properties
     * @return
     */
    public static LettuceConnectionFactory buildLettuceConnectionFactory(int dbIndex, ClientResources clientResources, RedisProperties properties){
        RedisStandaloneConfiguration redis1StandaloneConfiguration = getStandaloneConfig(dbIndex, properties);
        LettuceClientConfiguration clientConfig = getLettuceClientConfiguration(clientResources, properties);
        return new LettuceConnectionFactory(redis1StandaloneConfiguration, clientConfig);
    }

    /**
     * redis standalone config
     *
     * @param redisProperties redis 配置参数
     * @return RedisStandaloneConfiguration
     */
    private static RedisStandaloneConfiguration getStandaloneConfig(int dbIndex, RedisProperties redisProperties) {
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
        config.setHostName(redisProperties.getHost());
        config.setPort(redisProperties.getPort());
        config.setPassword(RedisPassword.of(redisProperties.getPassword()));
        config.setDatabase(dbIndex > -1 ? dbIndex : redisProperties.getDatabase());
        return config;
    }
    /**
     * redis standalone config
     *
     * @param redisProperties redis 配置参数
     * @return RedisStandaloneConfiguration
     */
    private static RedisStandaloneConfiguration getStandaloneConfig(RedisProperties redisProperties) {
        return getStandaloneConfig(-1, redisProperties);
    }

    /**
     * 构建 LettuceClientConfiguration
     *
     * @param clientResources clientResources
     * @param redisProperties redisProperties
     * @return LettuceClientConfiguration
     */
    private static LettuceClientConfiguration getLettuceClientConfiguration(ClientResources clientResources,
                                                                     RedisProperties redisProperties) {
        LettuceClientConfiguration.LettuceClientConfigurationBuilder builder =
                createBuilder(redisProperties.getLettuce().getPool());
        if (redisProperties.isSsl()) {
            builder.useSsl();
        }
        if (redisProperties.getTimeout() != null) {
            builder.commandTimeout(redisProperties.getTimeout());
        }
        if (redisProperties.getLettuce() != null) {
            RedisProperties.Lettuce lettuce = redisProperties.getLettuce();
            if (lettuce.getShutdownTimeout() != null
                    && !lettuce.getShutdownTimeout().isZero()) {
                builder.shutdownTimeout(
                        redisProperties.getLettuce().getShutdownTimeout());
            }
        }
        builder.clientResources(clientResources);
        return builder.build();
    }

    /**
     * 创建 LettuceClientConfigurationBuilder
     *
     * @param pool 连接池配置
     * @return LettuceClientConfigurationBuilder
     */
    private static LettuceClientConfiguration.LettuceClientConfigurationBuilder createBuilder(RedisProperties.Pool pool) {
        if (pool == null) {
            return LettuceClientConfiguration.builder();
        }
        return LettucePoolingClientConfiguration.builder()
                .poolConfig(getPoolConfig(pool));
    }

    /**
     * pool config
     *
     * @param properties redis 参数配置
     * @return GenericObjectPoolConfig
     */
    private static GenericObjectPoolConfig getPoolConfig(RedisProperties.Pool properties) {

        GenericObjectPoolConfig config = new GenericObjectPoolConfig();
        config.setMaxTotal(properties.getMaxActive());
        config.setMaxIdle(properties.getMaxIdle());
        config.setMinIdle(properties.getMinIdle());
        if (properties.getMaxWait() != null) {
            config.setMaxWaitMillis(properties.getMaxWait().toMillis());
        }
        return config;
    }
}
  •  RedisConfig 配置类

package com.dong.base.redis.config;

import com.dong.base.redis.core.BuildRedisConfig;
import com.dong.base.redis.core.MyRedisProperties;
import com.dong.base.redis.core.MyStringRedisTemplate;
import io.lettuce.core.resource.ClientResources;
import io.lettuce.core.resource.DefaultClientResources;
import lombok.Getter;
import lombok.Setter;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
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.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.StringRedisTemplate;

@Configuration
@ConfigurationProperties(prefix = "spring.redis")
@Getter
@Setter
public class RedisConfig {

    private MyRedisProperties master;

    private MyRedisProperties cache;

    @Bean(destroyMethod = "shutdown")
    @ConditionalOnMissingBean(ClientResources.class)
    public DefaultClientResources lettuceClientResources() {
        return DefaultClientResources.create();
    }

    @Bean(name = "redisTemplateMaster")
    @Primary
    public MyStringRedisTemplate stringRedisTemplate1(
            @Qualifier("RedisConnectionFactoryMaster") RedisConnectionFactory redisConnectionFactory,ClientResources clientResources) {
//        StringRedisTemplate template = new StringRedisTemplate();
//        template.setConnectionFactory(redisConnectionFactory);
        MyStringRedisTemplate template = new MyStringRedisTemplate(master,clientResources,redisConnectionFactory);
        return template;
    }

    @Bean(name = "RedisConnectionFactoryMaster")
    @Primary
    public LettuceConnectionFactory Redis1LettuceConnectionFactory(ClientResources clientResources) {
        return BuildRedisConfig.buildLettuceConnectionFactory(clientResources,master);
    }

    @Bean(name = "redisTemplateCache")
    public MyStringRedisTemplate stringRedisTemplate2(
            @Qualifier("RedisConnectionFactoryCache") RedisConnectionFactory redisConnectionFactory) {
        MyStringRedisTemplate template = new MyStringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean(name = "RedisConnectionFactoryCache")
    public LettuceConnectionFactory Redis2LettuceConnectionFactory(ClientResources clientResources) {
        return BuildRedisConfig.buildLettuceConnectionFactory(clientResources,cache);
    }



}
  • application.yml配置文件

在原来的默认redis配置文件中加入了dbList配置字,此处我用到了多数据源自行更改

spring:
  redis:
    master:
#      redis 持久化地址
      host: 127.0.0.1
      port: 6379
      password: 123132
      database: 15
      dbList: 0,1,2,3,4,5,6,7,8,9
    cache:
#      redis 缓存库的地址
      host: 127.0.0.1
      port: 7379
      password: 1231
      database: 0
  • 用法

MyStringRedisTemplate 直接操作走的默认数据(注:就是database配置)

MyStringRedisTemplate.getDbStringRedisTemplate(5)获取到需要操作的db的redisTemplate再去操作redis。

 

最后

以上就是慈祥大船为你收集整理的自研 spring boot 连接redis并动态切换database 多redisTemplate方法前要自定义RedisProperties自定义StringRedisTemplateBuildRedisConfig类 RedisConfig 配置类application.yml配置文件用法的全部内容,希望文章能够帮你解决自研 spring boot 连接redis并动态切换database 多redisTemplate方法前要自定义RedisProperties自定义StringRedisTemplateBuildRedisConfig类 RedisConfig 配置类application.yml配置文件用法所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(49)

评论列表共有 0 条评论

立即
投稿
返回
顶部