最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring工程中集成多個redis數(shù)據(jù)源的思路詳解

 更新時間:2025年07月28日 09:26:13   作者:亞林瓜子  
Spring項(xiàng)目集成雙Redis數(shù)據(jù)源需配置兩個連接工廠與RedisTemplate,通過@Primary指定默認(rèn)Bean,@Qualifier注入特定Bean,支持集群環(huán)境,本文給大家介紹Spring工程中集成多個redis數(shù)據(jù)源的相關(guān)知識,感興趣的朋友一起看看吧

問題

有個項(xiàng)目需要在同一個Spring工程中集成2個redis數(shù)據(jù)源。

思路

配置2個redis連接工廠,再配置2個redistemplate。然后,在使用緩存的時候,分別注入不同的redistemplate解決這個問題。這里主要是使用了spring中的2個注釋:

  • @Primary:設(shè)置默認(rèn)bean
  • @Qualifier:指定注入bean

解決

FhRedisConfig.java

這個類是配置第2個多余的redis,對application.yml文件中自定義redis配置映射類。如果application.yml文件中有如下配置:

fh:
	redis:
		host: 12.86.12.9
		password: swdghop
		port: 6379
		database:7

這對應(yīng)配置類如下:

package com.xxxx.framework.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
/**
 * redis配置類
 */
@Data
@ConfigurationProperties(prefix = "fh.redis")
public class FhRedisConfig {
    /**
     * 主機(jī)地址
     */
    private String host;
    /**
     * 密碼
     */
    private String password;
    /**
     * Redis 服務(wù)器端口號
     * 默認(rèn)值:6379(Redis 默認(rèn)端口)
     */
    private int port = 6381;
    /**
     * Redis 數(shù)據(jù)庫索引(0-15)
     * 默認(rèn)值:0
     */
    private int database = 0;
}

RedisConfig.java

這是redis配置類,這里主要配置2個redis連接工廠,2個redistemplate的bean。而且,使用@Primary設(shè)置redistemplate類注入的默認(rèn)bean為哪個redistemplate的bean。而且,如果增加了對redis集群配置的支持。

package com.xxxx.framework.config;
import io.lettuce.core.cluster.ClusterClientOptions;
import io.lettuce.core.cluster.ClusterTopologyRefreshOptions;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.RedisStaticMasterReplicaConfiguration;
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.script.DefaultRedisScript;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.util.CollectionUtils;
import javax.annotation.Resource;
import java.util.List;
/**
 * redis配置
 * 
 */
@Configuration
@EnableCaching
@EnableConfigurationProperties(FhRedisConfig.class)
public class RedisConfig extends CachingConfigurerSupport
{
    @Resource
    private FhRedisConfig fhRedisConfig;
    @Value("${spring.profiles.active:default}")
    private String activeProfile;
    /**
     * 默認(rèn)redis連接池
     * @return 默認(rèn)redis連接池
     */
    @Bean
    @Primary
    public RedisConnectionFactory redisConnectionFactory(RedisProperties redisProperties) {
        // 從 RedisProperties 提取連接池配置(如果存在)
        return getRedisConnectionFactory(redisProperties, redisProperties.getHost(), redisProperties.getPort(), redisProperties.getPassword(),
                redisProperties.getDatabase(), redisProperties.getCluster() == null ? null : redisProperties.getCluster().getNodes());
    }
    /**
     * redis連接池
     * @return redis連接池
     */
    @Bean
    public RedisConnectionFactory fhRedisConnectionFactory(RedisProperties redisProperties) {
        return getRedisConnectionFactory(redisProperties, fhRedisConfig.getHost(), fhRedisConfig.getPort(), fhRedisConfig.getPassword(),
                fhRedisConfig.getDatabase(), null);
    }
    /**
     * redis客戶端
     * @param connectionFactory redis連接池
     * @return redis客戶端
     */
    @Bean
    public RedisTemplate<Object, Object> fhRedisTemplate(@Qualifier("fhRedisConnectionFactory")RedisConnectionFactory connectionFactory)
    {
        return getRedisTemplate(connectionFactory);
    }
    /**
     * 默認(rèn)redis客戶端
     * @param connectionFactory 默認(rèn)redis連接池
     * @return 默認(rèn)redis客戶端
     */
    @Bean
    @Primary
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory connectionFactory)
    {
        return getRedisTemplate(connectionFactory);
    }
    private static RedisTemplate<Object, Object> getRedisTemplate(RedisConnectionFactory connectionFactory) {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(connectionFactory);
        FastJson2JsonRedisSerializer<Object> serializer = new FastJson2JsonRedisSerializer<>(Object.class);
        // 使用StringRedisSerializer來序列化和反序列化redis的key值
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(serializer);
        // Hash的key也采用StringRedisSerializer的序列化方式
        template.setHashKeySerializer(new StringRedisSerializer());
        template.setHashValueSerializer(serializer);
        template.afterPropertiesSet();
        return template;
    }
    private RedisConnectionFactory getRedisConnectionFactory(RedisProperties redisProperties, String host, int port, String password, int database, List<String> nodes) {
        LettuceConnectionFactory lettuceConnectionFactory;
        // 根據(jù)是否是集群模式選擇不同的配置
        if (!CollectionUtils.isEmpty(nodes)) {
            // 配置集群拓?fù)渌⑿逻x項(xiàng)
            ClusterTopologyRefreshOptions refreshOptions = ClusterTopologyRefreshOptions.builder()
                    .refreshPeriod(redisProperties.getLettuce().getCluster().getRefresh().getPeriod())
                    .enableAdaptiveRefreshTrigger(
                            ClusterTopologyRefreshOptions.RefreshTrigger.MOVED_REDIRECT,
                            ClusterTopologyRefreshOptions.RefreshTrigger.PERSISTENT_RECONNECTS)
                    .build();
            ClusterClientOptions clientOptions = ClusterClientOptions.builder()
                    .topologyRefreshOptions(refreshOptions)
                    .build();
            GenericObjectPoolConfig<?> poolConfig = getGenericObjectPoolConfig(redisProperties);
            LettucePoolingClientConfiguration.LettucePoolingSslClientConfigurationBuilder lettucePoolingSslClientConfigurationBuilder = LettucePoolingClientConfiguration.builder()
                    .clientOptions(clientOptions)
                    .poolConfig(poolConfig)  // 關(guān)鍵:設(shè)置連接池
                    .commandTimeout(redisProperties.getTimeout())
                    .useSsl();
            if (!activeProfile.equals("prod")) {
                lettucePoolingSslClientConfigurationBuilder.disablePeerVerification();
            }
            LettucePoolingClientConfiguration poolingClientConfig = lettucePoolingSslClientConfigurationBuilder.build();
            // 創(chuàng)建集群配置
            RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration(nodes);
            clusterConfig.setPassword(password);
            // 創(chuàng)建 LettuceConnectionFactory
            lettuceConnectionFactory = new LettuceConnectionFactory(clusterConfig, poolingClientConfig);
        } else {
            // 非集群模式保持原邏輯
            GenericObjectPoolConfig<?> poolConfig = getGenericObjectPoolConfig(redisProperties);
            LettucePoolingClientConfiguration.LettucePoolingSslClientConfigurationBuilder lettucePoolingSslClientConfigurationBuilder = LettucePoolingClientConfiguration.builder()
                    .poolConfig(poolConfig)  // 關(guān)鍵:設(shè)置連接池
                    .commandTimeout(redisProperties.getTimeout())
                    .useSsl();
            if (!activeProfile.equals("prod")) {
                lettucePoolingSslClientConfigurationBuilder.disablePeerVerification();
            }
            RedisStaticMasterReplicaConfiguration serverConfig = new RedisStaticMasterReplicaConfiguration(host, port);
            serverConfig.setPassword(password);
            LettucePoolingClientConfiguration poolingClientConfig = lettucePoolingSslClientConfigurationBuilder.build();
            lettuceConnectionFactory = new LettuceConnectionFactory(serverConfig, poolingClientConfig);
        }
        lettuceConnectionFactory.setDatabase(database);
        return lettuceConnectionFactory;
    }
    private static GenericObjectPoolConfig<?> getGenericObjectPoolConfig(RedisProperties redisProperties) {
        GenericObjectPoolConfig<?> poolConfig = new GenericObjectPoolConfig<>();
        if (redisProperties.getLettuce().getPool() != null) {
            RedisProperties.Pool poolProps = redisProperties.getLettuce().getPool();
            poolConfig.setMaxTotal(poolProps.getMaxActive());      // max-active
            poolConfig.setMaxIdle(poolProps.getMaxIdle());        // max-idle
            poolConfig.setMinIdle(poolProps.getMinIdle());        // min-idle
            poolConfig.setMaxWaitMillis(poolProps.getMaxWait().toMillis());        // max-wait
        }
        return poolConfig;
    }
}

注意@Qualifier注釋的使用,這里使用指定了特定的redis連接工廠。下面的在業(yè)務(wù)代碼中注入redistemaplte的時候,也需要使用呢@Qualifier注釋來使用特定的redis集群。

Controller.java

這是業(yè)務(wù)代碼中,注入使用特定的redis集群,如下代碼:

@Resource
@Qualifier("fhRedisTemplate")
private RedisTemplate<String, Integer> fhRedisTemplate;

如果不需要使用特定redis,只需要使用默認(rèn)redis則不需要@Qualifier注釋,如下:

@Resource
public RedisTemplate redisTemplate;

總結(jié)

這就是Spring項(xiàng)目redis多數(shù)據(jù)源問題。主要就是通過@Primary注釋來配置默認(rèn)bean,通過@Qualifier注釋來指定使用的bean。

參考

到此這篇關(guān)于Spring工程中集成多個redis數(shù)據(jù)源的思路詳解的文章就介紹到這了,更多相關(guān)Spring多個redis數(shù)據(jù)源內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • java多線程編程之使用Synchronized塊同步變量

    java多線程編程之使用Synchronized塊同步變量

    我們可以通過synchronized塊來同步特定的靜態(tài)或非靜態(tài)方法。要想實(shí)現(xiàn)這種需求必須為這些特性的方法定義一個類變量,然后將這些方法的代碼用synchronized塊括起來,并將這個類變量作為參數(shù)傳入synchronized塊
    2014-01-01
  • 淺析Java虛擬機(jī)詳解之概述、對象生存法則

    淺析Java虛擬機(jī)詳解之概述、對象生存法則

    這篇文章主要介紹了Java虛擬機(jī)詳解之概述、對象生存法則,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-04-04
  • java自定注解完整示例代碼

    java自定注解完整示例代碼

    Java注解是一種元數(shù)據(jù),可以提供有關(guān)程序代碼的額外信息,它們可以用于標(biāo)記類、方法、字段等元素,它允許我們在源代碼中嵌入元數(shù)據(jù)這篇文章主要介紹了java自定注解的相關(guān)資料,需要的朋友可以參考下
    2026-01-01
  • 淺談Java中的四種引用方式的區(qū)別

    淺談Java中的四種引用方式的區(qū)別

    下面小編就為大家?guī)硪黄獪\談Java中的四種引用方式的區(qū)別。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-09-09
  • JAVA最容易忽視的數(shù)據(jù)類型之枚舉詳解

    JAVA最容易忽視的數(shù)據(jù)類型之枚舉詳解

    這篇文章主要給大家介紹了關(guān)于JAVA最容易忽視的數(shù)據(jù)類型之枚舉的相關(guān)資料,Java中的枚舉類型是一種特殊的類型,它允許程序員定義一個固定的值集合,并為每個值分配一個名稱,枚舉類型提供了一種簡單、安全和可讀性強(qiáng)的方式來表示一組相關(guān)的常量,需要的朋友可以參考下
    2023-10-10
  • 深入淺析Java 抽象類和接口

    深入淺析Java 抽象類和接口

    這篇文章主要介紹了Java 抽象類和接口的相關(guān)知識,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2021-11-11
  • Java TreeSet類的簡單理解和使用

    Java TreeSet類的簡單理解和使用

    這篇文章主要介紹了Java TreeSet類的簡單理解和使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-02-02
  • springboot 自定義權(quán)限標(biāo)簽(tld),在freemarker引用操作

    springboot 自定義權(quán)限標(biāo)簽(tld),在freemarker引用操作

    這篇文章主要介紹了springboot 自定義權(quán)限標(biāo)簽(tld),在freemarker引用操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • java  工廠方法詳解及實(shí)例代碼

    java 工廠方法詳解及實(shí)例代碼

    這篇文章主要介紹了java 工廠方法詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • Java中接口的多態(tài)詳解

    Java中接口的多態(tài)詳解

    大家好,本篇文章主要講的是Java中接口的多態(tài)詳解,感興趣的同學(xué)趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-02-02

最新評論

五峰| 万全县| 巴彦淖尔市| 康马县| 灌云县| 临安市| 桦川县| 北碚区| 肇源县| 清水县| 南宁市| 原平市| 内乡县| 棋牌| 石景山区| 贵州省| 尉犁县| 革吉县| 剑川县| 黑水县| 三台县| 石屏县| 泽普县| 东丰县| 宁河县| 兴隆县| 内江市| 弋阳县| 尚志市| 三穗县| 治县。| 荣成市| 桐柏县| 永靖县| 翁源县| 南皮县| 黄山市| 台山市| 桃园市| 合江县| 宁陕县|