国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

SpringBoot Redis 配置多數(shù)據(jù)源

這篇具有很好參考價值的文章主要介紹了SpringBoot Redis 配置多數(shù)據(jù)源。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點擊"舉報違法"按鈕提交疑問。

Redis 從入門到精通【應(yīng)用篇】之SpringBoot Redis 配置多數(shù)據(jù)源


SpringBoot Redis 配置多數(shù)據(jù)源,Redis從入門到精通2023版,spring boot,redis,java,緩存,后端
使用 RedisTemplate 支持多個 Redis 數(shù)據(jù)庫

0. Redis從入門到精通系列文章

  1. 《Redis 從入門到精通【進(jìn)階篇】之Lua腳本詳解》
  2. 《Redis 從入門到精通【實踐篇】SpringBoot Redis 配置多數(shù)據(jù)源》
  3. 《Redis 從入門到精通【進(jìn)階篇】三分鐘了解Redis地理位置數(shù)據(jù)結(jié)構(gòu)GeoHash》
  4. 《Redis 從入門到精通【進(jìn)階篇】一文學(xué)會Lua腳本》
  5. 《Redis使用Lua腳本和Redisson來保證庫存扣減中的原子性和一致性》
  6. 《SpringBoot Redis 使用Lettuce和Jedis配置哨兵模式》
  7. 《Redis【應(yīng)用篇】之RedisTemplate基本操作》
  8. 《Redis 從入門到精通【實踐篇】之SpringBoot配置Redis多數(shù)據(jù)源》
  9. 《Redis 從入門到精通【進(jìn)階篇】之三分鐘了解Redis HyperLogLog 數(shù)據(jù)結(jié)構(gòu)》
  10. 《Redis 從入門到精通【進(jìn)階篇】之三分鐘了解Redis地理位置數(shù)據(jù)結(jié)構(gòu)GeoHash》
  11. 《Redis 從入門到精通【進(jìn)階篇】之高可用哨兵機制(Redis Sentinel)詳解》
  12. 《Redis 從入門到精通【進(jìn)階篇】之redis主從復(fù)制詳解》
  13. 《Redis 從入門到精通【進(jìn)階篇】之Redis事務(wù)詳解》
  14. 《Redis從入門到精通【進(jìn)階篇】之對象機制詳解》
  15. 《Redis從入門到精通【進(jìn)階篇】之消息傳遞發(fā)布訂閱模式詳解》
  16. 《Redis從入門到精通【進(jìn)階篇】之持久化 AOF詳解》
  17. 《Redis從入門到精通【進(jìn)階篇】之持久化RDB詳解》
  18. 《Redis從入門到精通【高階篇】之底層數(shù)據(jù)結(jié)構(gòu)字典(Dictionary)詳解》
  19. 《Redis從入門到精通【高階篇】之底層數(shù)據(jù)結(jié)構(gòu)快表QuickList詳解》
  20. 《Redis從入門到精通【高階篇】之底層數(shù)據(jù)結(jié)構(gòu)簡單動態(tài)字符串(SDS)詳解》
  21. 《Redis從入門到精通【高階篇】之底層數(shù)據(jù)結(jié)構(gòu)壓縮列表(ZipList)詳解》
  22. 《Redis從入門到精通【進(jìn)階篇】之?dāng)?shù)據(jù)類型Stream詳解和使用示例》

感謝@愛喝茶同學(xué)和其他幾位同學(xué)的問題反饋。對Redis多數(shù)據(jù)源進(jìn)行了改造升級,兼容不同版本和硬編碼配置項的問題,將Jedis 替換為Lettuce, 支持<=Spring boot 2.7.12

1.教程

0. 添加依賴

在項目中使用 RedisTemplate 支持多個 Redis 數(shù)據(jù)庫之前,需要先添加 Spring Data Redis 的依賴。在 Maven 項目中,可以通過在 pom.xml 文件中添加以下依賴來引入 Spring Data Redis:

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

<spring-boot.version>2.7.12</spring-boot.version>

1. 配置多個 Redis 連接信息

在 Spring Boot 中,可以通過在 application.properties 或 application.yml 文件中指定不同的 Redis 連接信息來配置多個 RedisConnectionFactory 實例,并通過 @Bean 注解將它們注入到 RedisTemplate 中,例如:
Redis的常用配置大概是這些

# Redis 服務(wù)器的主機名或 IP 地址
spring.redis.host=127.0.0.1

# Redis 服務(wù)器的端口號
spring.redis.port=6379

# Redis 服務(wù)器的密碼,如果沒有設(shè)置密碼,則為空字符串
spring.redis.password=

# Redis 數(shù)據(jù)庫的編號,默認(rèn)為 0
spring.redis.database=0

# Redis 服務(wù)器連接超時時間(毫秒),默認(rèn)為 5000 毫秒
spring.redis.timeout=5000

# 連接池最大連接數(shù),即最多允許多少個客戶端同時連接到 Redis 服務(wù)器
spring.redis.pool.max-active=8

# 連接池中最大空閑連接數(shù),即在連接池中最多允許多少個連接處于空閑狀態(tài)
spring.redis.pool.max-idle=8

# 連接池中最小空閑連接數(shù),即在連接池中最少保持多少個連接處于空閑狀態(tài)
spring.redis.pool.min-idle=0

# 連接池最大等待時間(毫秒),即當(dāng)連接池中的連接全部被占用時,新的連接請求最多等待多長時間
# 如果設(shè)置為-1,則表示無限等待
spring.redis.pool.max-wait=-1

# 是否啟用 SSL 加密連接,默認(rèn)為 false
spring.redis.ssl=false

我們將上面的配置改造一下,支持Redis多數(shù)據(jù)源

有同學(xué)反饋之前的寫法有兩方面問題,配置寫死了,新增一個Redis 實例,需要改代碼。還有一個問題是如果沒有排除spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration 會報錯
所以本次進(jìn)行修正。將配置支持不限個數(shù)的Redis數(shù)據(jù)源,將Jedis 客戶端改為了lettuce Spring boot版本升級為<spring-boot.version>2.7.12</spring-boot.version>



# 配置 Redis 數(shù)據(jù)庫 主數(shù)據(jù)源
spring.redis.master.host=172.0.0.1
spring.redis.master.port=6379
spring.redis.master.password=
spring.redis.master.database=15
spring.redis.master.timeout=5000
spring.redis.master.pool.max-active=8
spring.redis.master.pool.max-idle=8
spring.redis.master.pool.min-idle=0
spring.redis.master.pool.max-wait=-1
spring.redis.master.ssl=false

# 配置 Redis 數(shù)據(jù)庫 0

spring.redis.database0.host=172.0.0.1
spring.redis.database0.port=6379
spring.redis.database0.password=
spring.redis.database0.database=0
spring.redis.database0.timeout=5000
spring.redis.database0.pool.max-active=8
spring.redis.database0.pool.max-idle=8
spring.redis.database0.pool.min-idle=0
spring.redis.database0.pool.max-wait=-1
spring.redis.database0.ssl=false

# 配置 Redis 數(shù)據(jù)庫 1
spring.redis.database1.host=172.0.0.1
spring.redis.database1.port=6379
spring.redis.database1.password=
spring.redis.database1.database=1
spring.redis.database1.timeout=5000
spring.redis.database1.pool.max-active=8
spring.redis.database1.pool.max-idle=8
spring.redis.database1.pool.min-idle=0
spring.redis.database1.pool.max-wait=-1
spring.redis.database1.ssl=false

2. 配置

@ConfigurationProperties(prefix = "spring.redis.database0")@ConfigurationProperties(prefix = "spring.redis.database1") 注解來將不同的 Redis 配置注入到 Java 類中,例如:

 package com.icepip.project;

import com.alibaba.nacos.common.utils.StringUtils;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.MutablePropertyValues;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanPostProcessor;
import org.springframework.beans.factory.config.ConstructorArgumentValues;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.data.redis.connection.*;
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.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;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

@Configuration
@ConfigurationProperties(prefix = "spring")
public class RedisConfig implements ApplicationContextAware, InitializingBean, BeanPostProcessor {
    /**
     * 將多個Redis 數(shù)據(jù)源的配置信息放到一個Map中,然后遍歷Map 創(chuàng)建不同的RedisTemplate實例
     * Map<String, Map<String, Object>> redis 中的 key 為配置的spring.redis.xx  xx為key  value xx一組的值組裝成了map
     * 創(chuàng)建的RedisTemplate實例的名稱為 xxRedisTemplate
     */
    protected static Map<String, Map<String, Object>> redis = new HashMap<>();
    // 配置主數(shù)據(jù)源
    @Value("${primary.redis.key:master}")
    private String primaryKey;
    private static ApplicationContext applicationContext;

    public RedisConfig() {
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) {
        RedisConfig.applicationContext = applicationContext;
    }

    @Override
    public void afterPropertiesSet() {
        redis.forEach((k, v) -> {
            if (Objects.equals(k, this.primaryKey)) {
                Map<String, Object> paramMap = new HashMap(4);
                v.forEach((k1, v1) -> {
                    paramMap.put("spring.redis." + k1, v1);
                });
                MapPropertySource mapPropertySource = new MapPropertySource("redisAutoConfigProperty", paramMap);
                ((StandardEnvironment) applicationContext.getEnvironment()).getPropertySources().addLast(mapPropertySource);
            }
            RedisConnectionFactory lettuceConnectionFactory = this.buildLettuceConnectionFactory(k, v, this.buildGenericObjectPoolConfig(k, v));
            this.buildRedisTemplate(k, lettuceConnectionFactory);
            this.buildStringRedisTemplate(k, lettuceConnectionFactory);
        });
    }


    @Bean
    public RedisTemplate<Object, Object> redisTemplate() {
        Map<String, Object> redisParam = redis.get(this.primaryKey);
        GenericObjectPoolConfig<?> genericObjectPoolConfig = this.buildGenericObjectPoolConfig(this.primaryKey, redisParam);
        RedisConnectionFactory lettuceConnectionFactory = this.buildLettuceConnectionFactory(this.primaryKey, redisParam, genericObjectPoolConfig);
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(lettuceConnectionFactory);
        return template;
    }

    @Bean
    @ConditionalOnMissingBean
    public StringRedisTemplate stringRedisTemplate() {
        Map<String, Object> redisParam = redis.get(this.primaryKey);
        GenericObjectPoolConfig<?> genericObjectPoolConfig = this.buildGenericObjectPoolConfig(this.primaryKey, redisParam);
        RedisConnectionFactory lettuceConnectionFactory = this.buildLettuceConnectionFactory(this.primaryKey, redisParam, genericObjectPoolConfig);
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(lettuceConnectionFactory);
        return template;
    }


    private void buildStringRedisTemplate(String k, RedisConnectionFactory lettuceConnectionFactory) {
        ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
        constructorArgumentValues.addIndexedArgumentValue(0, lettuceConnectionFactory);
        this.setCosBean(k + "StringRedisTemplate", StringRedisTemplate.class, constructorArgumentValues);
    }

    private void buildRedisTemplate(String k, RedisConnectionFactory lettuceConnectionFactory) {
        Jackson2JsonRedisSerializer<?> serializer = new Jackson2JsonRedisSerializer<>(Object.class);
        ObjectMapper mapper = new ObjectMapper();
        mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        serializer.setObjectMapper(mapper);
        Map<String, Object> original = new HashMap<>(2);
        original.put("connectionFactory", lettuceConnectionFactory);
        original.put("valueSerializer", serializer);
        original.put("keySerializer", new StringRedisSerializer());
        original.put("hashKeySerializer", new StringRedisSerializer());
        original.put("hashValueSerializer", serializer);
        this.setBean(k + "RedisTemplate", RedisTemplate.class, original);
    }

    public GenericObjectPoolConfig<?> buildGenericObjectPoolConfig(String redisKey, Map<String, Object> param) {
        GenericObjectPoolConfig<?> result;
        if (applicationContext.containsBean(redisKey + "GenericObjectPoolConfig")) {
            result = getBean(redisKey + "GenericObjectPoolConfig");
        } else {
            Map<String, Object> original = new HashMap<>(8);
            original.put("maxTotal", param.getOrDefault("maxTotal", 8));
            original.put("maxIdle", param.getOrDefault("maxIdle", 8));
            original.put("minIdle", param.getOrDefault("minIdle", 0));
            original.put("maxWaitMillis", param.getOrDefault("maxWaitMillis", -1L));
            original.put("testOnBorrow", param.getOrDefault("testOnBorrow", Boolean.FALSE));
            this.setBean(redisKey + "GenericObjectPoolConfig", GenericObjectPoolConfig.class, original);
            result = getBean(redisKey + "GenericObjectPoolConfig");
        }


        return result;
    }

    public RedisConnectionFactory buildLettuceConnectionFactory(String redisKey, Map<String, Object> param, GenericObjectPoolConfig genericObjectPoolConfig) {
        if (!applicationContext.containsBean(redisKey + "redisConnectionFactory")) {
            long timeout = Long.parseLong((String) param.getOrDefault("timeout", "3000"));
            LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration.builder().commandTimeout(Duration.ofMillis(timeout)).poolConfig(genericObjectPoolConfig).build();
            RedisConfiguration firstArgument = null;
            // 根據(jù)配置項判斷是否是集群或者哨兵或者單機
            if (this.isCluster(param)) {
                firstArgument = this.buildClusterConfig(param);
            } else if (this.isSentinel(param)) {
                firstArgument = this.buildSentinelConfig(param);
            } else {
                firstArgument = this.buildStandaloneConfig(param);
            }

            ConstructorArgumentValues constructorArgumentValues = new ConstructorArgumentValues();
            constructorArgumentValues.addIndexedArgumentValue(0, firstArgument);
            constructorArgumentValues.addIndexedArgumentValue(1, clientConfig);
            this.setCosBean(redisKey + "redisConnectionFactory", LettuceConnectionFactory.class, constructorArgumentValues);
        }
        return getBean(redisKey + "redisConnectionFactory");
    }


    private RedisStandaloneConfiguration buildStandaloneConfig(Map<String, Object> param) {
        RedisStandaloneConfiguration standaloneConfig = new RedisStandaloneConfiguration();
        standaloneConfig.setHostName(String.valueOf(param.get("host")));
        standaloneConfig.setDatabase(Integer.parseInt((String) param.get("database")));
        standaloneConfig.setPort(Integer.parseInt((String) param.get("port")));
        standaloneConfig.setPassword(RedisPassword.of((String) param.get("password")));
        return standaloneConfig;
    }

    private RedisSentinelConfiguration buildSentinelConfig(Map<String, Object> param) {
        RedisSentinelConfiguration config = new RedisSentinelConfiguration();
        // todo 如果是哨兵模式需要要在此處額外的配置,可以完善
        return config;
    }

    private RedisClusterConfiguration buildClusterConfig(Map<String, Object> param) {
        RedisClusterConfiguration config = new RedisClusterConfiguration();
        // todo 如果是Cluster模式需要在此處額外的配置,可以完善
        return config;
    }


    private static void checkApplicationContext() {
        if (applicationContext == null) {
            throw new IllegalStateException("applicaitonContext未注入,請在applicationContext.xml中定義SpringContextUtil");
        }
    }

    public static <T> T getBean(String name) {
        checkApplicationContext();
        return applicationContext.containsBean(name) ? (T) applicationContext.getBean(name) : null;
    }


    public synchronized void setBean(String beanName, Class<?> clazz, Map<String, Object> original) {
        checkApplicationContext();
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
        if (!beanFactory.containsBean(beanName)) {
            GenericBeanDefinition definition = new GenericBeanDefinition();
            definition.setBeanClass(clazz);
            if (beanName.startsWith(this.primaryKey)) {
                definition.setPrimary(true);
            }
            definition.setPropertyValues(new MutablePropertyValues(original));
            beanFactory.registerBeanDefinition(beanName, definition);
        }
    }

    public synchronized void setCosBean(String beanName, Class<?> clazz, ConstructorArgumentValues original) {
        checkApplicationContext();
        DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
        if (!beanFactory.containsBean(beanName)) {
            GenericBeanDefinition definition = new GenericBeanDefinition();
            definition.setBeanClass(clazz);
            if (beanName.startsWith(this.primaryKey)) {
                definition.setPrimary(true);
            }

            definition.setConstructorArgumentValues(new ConstructorArgumentValues(original));
            beanFactory.registerBeanDefinition(beanName, definition);
        }
    }

    private boolean isSentinel(Map<String, Object> param) {
        String sentinelMaster = (String) param.get("sentinel.master");
        String sentinelNodes = (String) param.get("sentinel.nodes");
        return StringUtils.isNotEmpty(sentinelMaster) && StringUtils.isNotEmpty(sentinelNodes);
    }

    private boolean isCluster(Map<String, Object> param) {
        String clusterNodes = (String) param.get("cluster.nodes");
        return StringUtils.isNotEmpty(clusterNodes);
    }


    public Map<String, Map<String, Object>> getRedis() {
        return redis;
    }
}

使用 @ConfigurationProperties(prefix = "spring") 注解將不同的redis Map配置 實例中,并通過動態(tài)構(gòu)造 RedisTemplate 實例.并且放置到Spring容器中, 這樣,在代碼中就可以通過 @Qualifier 注解來注入不同的 RedisTemplate 實例,從而訪問不同的 Redis 數(shù)據(jù)庫。還有同學(xué)反饋 需要有個主Redis 實例,所以又把RedisTemplate 手動構(gòu)造了一份放置容器

3. 使用 RedisTemplate 實例

在 Spring Boot 中,可以通過 @Qualifier@Autowired 注解將不同的 RedisTemplate 實例注入到 Java 類中,例如:

   @RestController
public class ConsumerController {

    @Autowired
    private RedisTemplate<Object, Object> redisTemplate;
    @Autowired
    private StringRedisTemplate  stringRedisTemplate;
    @Autowired
    @Qualifier("database0RedisTemplate")
    private RedisTemplate<Object, Object> redisTemplate0;

    @Autowired
    @Qualifier("database1RedisTemplate")
    private RedisTemplate<Object, Object> redisTemplate1;

    @Autowired
    @Qualifier("database0StringRedisTemplate")
    private StringRedisTemplate stringRedisTemplate0;

    @Autowired
    @Qualifier("database1StringRedisTemplate")
    private StringRedisTemplate stringRedisTemplate1;

    @GetMapping("/call")
    public String call() {
        return "call";
    }

    @GetMapping("/save")
    public String save() {
        return "save";
    }
}

4. 使用 RedisTemplate 操作 Redis

在 RedisTemplate 中,提供了一系列方法來操作 Redis,例如:

// 存儲數(shù)據(jù)到 Redis 數(shù)據(jù)庫 0
redisTemplate0.opsForValue().set("key0", "value0");
// 獲取數(shù)據(jù)從 Redis 數(shù)據(jù)庫 0
Object value0 = redisTemplate0.opsForValue().get("key0");
// 刪除數(shù)據(jù)從 Redis 數(shù)據(jù)庫 0
redisTemplate0.delete("key0");

// 存儲數(shù)據(jù)到 Redis 數(shù)據(jù)庫 1
redisTemplate1.opsForValue().set("key1", "value1");
// 獲取數(shù)據(jù)從 Redis 數(shù)據(jù)庫 1
Object value1 = redisTemplate1.opsForValue().get("key1");
// 刪除數(shù)據(jù)從 Redis 數(shù)據(jù)庫 1
redisTemplate1.delete("key1");

2. 常見問題

按照之前版本在使用 Spring Boot 中的 Redis 進(jìn)行多數(shù)據(jù)源配置時,可能會遇到以下幾個常見問題,新版本應(yīng)該不會遇到,已經(jīng)做了兼容。

2.1. RedisTemplate 實例重名問題

在配置多個 Redis 數(shù)據(jù)庫時,需要為每個 Redis 數(shù)據(jù)庫創(chuàng)建一個 RedisTemplate 實例。如果不同的 RedisTemplate 實例的名稱相同,可能會導(dǎo)致實例重名的問題,進(jìn)而導(dǎo)致應(yīng)用程序無法啟動。為每個 RedisTemplate 實例指定不同的名稱。例如,可以在配置類中通過 @Bean 注解為每個 RedisTemplate 實例指定名稱

@Bean(name = "redisTemplate0")
public RedisTemplate<String, Object> redisTemplate0(RedisConnectionFactory redisConnectionFactory0) {
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(redisConnectionFactory0);
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
    redisTemplate.afterPropertiesSet();
    return redisTemplate;
}

@Bean(name = "redisTemplate1")
public RedisTemplate<String, Object> redisTemplate1(RedisConnectionFactory redisConnectionFactory1) {
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(redisConnectionFactory1);
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
    redisTemplate.afterPropertiesSet();
    return redisTemplate;
}

在上面的代碼中,我們分別為兩個 RedisTemplate 實例指定了不同的名稱,分別為 “redisTemplate0” 和 “redisTemplate1”。

2.2. RedisConnectionFactory 實例重用問題

在配置多個 Redis 數(shù)據(jù)庫時,需要為每個 Redis 數(shù)據(jù)庫創(chuàng)建一個 RedisConnectionFactory 實例。如果多個 RedisConnectionFactory 實例使用了同一個 Redis 連接池,可能會導(dǎo)致實例重用的問題,進(jìn)而導(dǎo)致應(yīng)用程序無法啟動??梢詾槊總€ RedisConnectionFactory 實例配置不同的 Redis 連接池。例如,可以在配置類中創(chuàng)建不同的 RedisConnectionFactory 實例,并分別為它們配置不同的 Redis 連接池

@Bean(name = "redisConnectionFactory0")
public RedisConnectionFactory redisConnectionFactory0() {
    RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
    config.setHostName("localhost");
    config.setPort(6379);
    config.setPassword(RedisPassword.of("password"));
    LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(config);
    connectionFactory.setDatabase(0);
    connectionFactory.afterPropertiesSet();
    return connectionFactory;
}

@Bean(name = "redisConnectionFactory1")
public RedisConnectionFactory redisConnectionFactory1() {
    RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
    config.setHostName("localhost");
    config.setPort(6379);
    config.setPassword(RedisPassword.of("password"));
    LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(config);
    connectionFactory.setDatabase(1);
    connectionFactory.afterPropertiesSet();
    return connectionFactory;
}

2.3. 數(shù)據(jù)庫編號配置問題

在配置多個 Redis 數(shù)據(jù)庫時,需要為每個 Redis 數(shù)據(jù)庫指定不同的數(shù)據(jù)庫編號。如果多個 Redis 數(shù)據(jù)庫使用了同一個數(shù)據(jù)庫編號,可能會導(dǎo)致數(shù)據(jù)被覆蓋或丟失。為了解決這個問題,可以為每個 RedisConnectionFactory 實例配置不同的數(shù)據(jù)庫編號。例如,可以在 RedisStandaloneConfiguration 中指定不同的數(shù)據(jù)庫編號

@Bean(name = "redisConnectionFactory0")
public RedisConnectionFactory redisConnectionFactory0() {
    RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
    config.setHostName("localhost");
    config.setPort(6379);
    config.setPassword(RedisPassword.of("password"));
    config.setDatabase(0);
    LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(config);
    connectionFactory.afterPropertiesSet();
    return connectionFactory;
}

@Bean(name = "redisConnectionFactory1")
public RedisConnectionFactory redisConnectionFactory1() {
    RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
    config.setHostName("localhost");
    config.setPort(6379);
    config.setPassword(RedisPassword.of("password"));
    config.setDatabase(1);
    LettuceConnectionFactory connectionFactory = new LettuceConnectionFactory(config);
    connectionFactory.afterPropertiesSet();
    return connectionFactory;
}

2.4. RedisTemplate 序列化問題

在使用 RedisTemplate 時,需要對數(shù)據(jù)進(jìn)行序列化和反序列化。如果不同的 Redis 數(shù)據(jù)庫使用了不同的序列化方式,可能會導(dǎo)致數(shù)據(jù)無法正常讀寫。每個 RedisTemplate 實例指定不同的序列化器。例如,可以為每個 RedisTemplate 實例分別設(shè)置不同的 keySerializer 和 valueSerializer 。但是通常情況下我們的的項目中的序列化方式都是一致的,除非是在連別的項目的Redis時候人家已經(jīng)按自己的序列化方式將值已經(jīng)寫入,我們只能按照對接方的方式配置序列化。

@Bean(name = "redisTemplate0")
public RedisTemplate<String, Object> redisTemplate0(RedisConnectionFactory redisConnectionFactory0) {
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(redisConnectionFactory0);
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
    redisTemplate.afterPropertiesSet();
    return redisTemplate;
}

@Bean(name = "redisTemplate1")
public RedisTemplate<String, Object> redisTemplate1(RedisConnectionFactory redisConnectionFactory1) {
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
    redisTemplate.setConnectionFactory(redisConnectionFactory1);
    redisTemplate.setKeySerializer(new StringRedisSerializer());
    redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
    redisTemplate.afterPropertiesSet();
    return redisTemplate;
}

SpringBoot Redis 配置多數(shù)據(jù)源,Redis從入門到精通2023版,spring boot,redis,java,緩存,后端大家好,我是冰點,今天的Redis【實踐篇】之SpringBoot Redis 配置多數(shù)據(jù)源,全部內(nèi)容就是這些。如果你有疑問或見解可以在評論區(qū)留言。文章來源地址http://www.zghlxwxcb.cn/news/detail-599074.html

到了這里,關(guān)于SpringBoot Redis 配置多數(shù)據(jù)源的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實不符,請點擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實,立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費用

相關(guān)文章

  • springboot之多數(shù)據(jù)源配置

    springboot之多數(shù)據(jù)源配置

    實際開發(fā)中,進(jìn)場可能遇到在一個引用中可能需要訪問多個數(shù)據(jù)庫的情況,以下是兩種典型場景: 數(shù)據(jù)分布在不同的數(shù)據(jù)庫匯總,數(shù)據(jù)庫拆了,應(yīng)用沒拆。一個公司多個子項目,各用各的數(shù)據(jù)庫,涉及數(shù)據(jù)共享。。。。 為了解決數(shù)據(jù)庫的讀性能瓶頸(讀比寫性能更高,寫鎖

    2024年02月07日
    瀏覽(26)
  • Springboot+Druid配置多數(shù)據(jù)源

    Spring的多數(shù)據(jù)源支持—AbstractRoutingDataSource,AbstractRoutingDataSource定義了抽象的determineCurrentLookupKey方法,子類實現(xiàn)此方法,來確定要使用的數(shù)據(jù)源 Druid 實現(xiàn)多數(shù)據(jù)源支持,核心是Overwrite AbstractRoutingDataSource 的 determineCurrentLookupKey 方法 以springboot框架為基礎(chǔ)使用aop注解的方式依賴

    2024年02月11日
    瀏覽(26)
  • ruoyi(若依)配置多數(shù)據(jù)源(mysql+postgresql),rouyi(Springboot)多數(shù)據(jù)源設(shè)置

    ruoyi(若依)配置多數(shù)據(jù)源(mysql+postgresql),rouyi(Springboot)多數(shù)據(jù)源設(shè)置

    (1)修改DatasourceType (2)修改DruidConfig,這里有很多細(xì)節(jié)要注意,就是大小寫的問題 (3)使用選擇數(shù)據(jù)源,會自動切換數(shù)據(jù)源

    2024年02月16日
    瀏覽(33)
  • SpringBoot整合Druid配置多數(shù)據(jù)源

    SpringBoot整合Druid配置多數(shù)據(jù)源

    目錄 1.初始化項目 1.1.初始化工程 1.2.添加依賴 1.3.配置yml文件 1.4.Spring Boot 啟動類中添加?@MapperScan?注解,掃描 Mapper 文件夾 1.5.配置使用數(shù)據(jù)源 1.5.1.注解方式 1.5.2.基于AOP手動實現(xiàn)多數(shù)據(jù)源原生的方式 2.結(jié)果展示 Mybatis-Plus:簡介 | MyBatis-Plus (baomidou.com) 在正式開始之前,先初始

    2024年02月01日
    瀏覽(38)
  • springboot+mybatis+pgsql多數(shù)據(jù)源配置

    springboot+mybatis+pgsql多數(shù)據(jù)源配置

    jdk環(huán)境:1.8 配置了雙數(shù)據(jù)源 pgsql+pgsql ? 第一個配置文件 :PrimaryDataSourceConfig 參數(shù)詳情 :@Primary //指定你主要的數(shù)據(jù)源是哪一個 例如:我這里主要數(shù)據(jù)源是第一個配置文件 所以我的第二個配置文件并沒有加這個注解 注意修改: @MapperScan里面的basePackages @ConfigurationProperties里面

    2024年02月03日
    瀏覽(19)
  • springboot整合druid及多數(shù)據(jù)源配置

    springboot整合druid及多數(shù)據(jù)源配置

    本篇主要分兩部分 ①springboot整合druid的代碼配置,以及druid的監(jiān)控頁面演示;②對實際場景中多數(shù)據(jù)源的配置使用進(jìn)行講解。 可以用idea快速生成一個可運行的demo工程,具體可以參考如何快速創(chuàng)建springboot項目 主要用到的依賴如下: ?配置數(shù)據(jù)庫需要的配置文件application.yml( 注

    2024年02月12日
    瀏覽(31)
  • SpringBoot結(jié)合MyBatis實現(xiàn)多數(shù)據(jù)源配置

    SpringBoot結(jié)合MyBatis實現(xiàn)多數(shù)據(jù)源配置

    SpringBoot框架實現(xiàn)多數(shù)據(jù)源操作,首先需要搭建Mybatis的運行環(huán)境。 由于是多數(shù)據(jù)源,也就是要有多個數(shù)據(jù)庫,所以,我們創(chuàng)建兩個測試數(shù)據(jù)庫,分別是:【sp-demo01】和【sp-demo02】,如下圖所示: 具體SQL代碼: 創(chuàng)建【sp-demo01】數(shù)據(jù)庫。 創(chuàng)建【sp-demo02】數(shù)據(jù)庫。 MyBatis框架中,

    2024年02月09日
    瀏覽(15)
  • SpringBoot+mybatis+pgsql多個數(shù)據(jù)源配置

    SpringBoot+mybatis+pgsql多個數(shù)據(jù)源配置

    jdk環(huán)境:1.8 配置了雙數(shù)據(jù)源springboot+druid+pgsql,application.properties配置修改如下: 主數(shù)據(jù)庫注入 從數(shù)據(jù)庫Java代碼: ? ? ?這里就就不一一貼代碼了,主要是接口對應(yīng)mybatis xml配置文件。項目文件接口如下: 創(chuàng)建成以上目錄就可以了,分別是dao接口、Java數(shù)據(jù)源配置、mybatis映射

    2024年02月11日
    瀏覽(27)
  • springboot實現(xiàn)多數(shù)據(jù)源配置(Druid/Hikari)

    springboot實現(xiàn)多數(shù)據(jù)源配置(Druid/Hikari)

    使用springboot+mybatis-plus+(Druid/Hikari)實現(xiàn)多數(shù)據(jù)源配置 操作步驟: 引入相應(yīng)的maven坐標(biāo) 編寫mybatis配置,集成mybatis或mybatis-plus(如果已集成可跳過) 編寫數(shù)據(jù)源配置類 編寫注解,并通過aop進(jìn)行增強(編寫數(shù)據(jù)源切換代碼) 類或方法中使用注解,對數(shù)據(jù)源進(jìn)行切換 第一步:

    2024年02月13日
    瀏覽(25)
  • 【精·超詳細(xì)】SpringBoot 配置多個數(shù)據(jù)源(連接多個數(shù)據(jù)庫)

    【精·超詳細(xì)】SpringBoot 配置多個數(shù)據(jù)源(連接多個數(shù)據(jù)庫)

    目錄 1.項目路徑 2.pom.xml? 引入依賴: 3.application.yml配置文件: 4.兩個entity類 5.Conroller 6.兩個Service以及兩個ServiceImpl? 7.兩個Mapper及兩個Mapper.xml? 8.運行Application? 然后在瀏覽器請求 9.查看兩個數(shù)據(jù)庫是否有新增數(shù)據(jù) ? ? ? ? ? 總結(jié): 1.pom.xml 引入依賴: dynamic-datasource-spring-b

    2024年02月12日
    瀏覽(42)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包