欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

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

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

問(wèn)題

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

思路

配置2個(gè)redis連接工廠,再配置2個(gè)redistemplate。然后,在使用緩存的時(shí)候,分別注入不同的redistemplate解決這個(gè)問(wèn)題。這里主要是使用了spring中的2個(gè)注釋?zhuān)?/p>

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

解決

FhRedisConfig.java

這個(gè)類(lèi)是配置第2個(gè)多余的redis,對(duì)application.yml文件中自定義redis配置映射類(lèi)。如果application.yml文件中有如下配置:

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

這對(duì)應(yīng)配置類(lèi)如下:

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

RedisConfig.java

這是redis配置類(lèi),這里主要配置2個(gè)redis連接工廠,2個(gè)redistemplate的bean。而且,使用@Primary設(shè)置redistemplate類(lèi)注入的默認(rèn)bean為哪個(gè)redistemplate的bean。而且,如果增加了對(duì)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客戶(hù)端
     * @param connectionFactory redis連接池
     * @return redis客戶(hù)端
     */
    @Bean
    public RedisTemplate<Object, Object> fhRedisTemplate(@Qualifier("fhRedisConnectionFactory")RedisConnectionFactory connectionFactory)
    {
        return getRedisTemplate(connectionFactory);
    }
    /**
     * 默認(rèn)redis客戶(hù)端
     * @param connectionFactory 默認(rèn)redis連接池
     * @return 默認(rèn)redis客戶(hù)端
     */
    @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來(lái)序列化和反序列化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的時(shí)候,也需要使用呢@Qualifier注釋來(lái)使用特定的redis集群。

Controller.java

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

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

如果不需要使用特定redis,只需要使用默認(rèn)redis則不需要@Qualifier注釋?zhuān)缦拢?/p>

@Resource
public RedisTemplate redisTemplate;

總結(jié)

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

參考

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

相關(guān)文章

  • MyBatis Plus復(fù)合主鍵問(wèn)題的解決

    MyBatis Plus復(fù)合主鍵問(wèn)題的解決

    在數(shù)據(jù)庫(kù)設(shè)計(jì)中,有時(shí)候需要使用復(fù)合主鍵來(lái)唯一標(biāo)識(shí)表中的一行數(shù)據(jù),本文將為您詳細(xì)介紹MyBatis Plus中復(fù)合主鍵的問(wèn)題以及解決方案,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-09-09
  • java 字符串分割的三種方法(總結(jié))

    java 字符串分割的三種方法(總結(jié))

    下面小編就為大家?guī)?lái)一篇java 字符串分割的三種方法(總結(jié))。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2016-11-11
  • Java詳解表格的創(chuàng)建與使用流程

    Java詳解表格的創(chuàng)建與使用流程

    這篇文章主要介紹了怎么用Java來(lái)創(chuàng)建和使用表格,表格是我們經(jīng)常要用的工具,但是你有想過(guò)自己怎么去實(shí)現(xiàn)它嗎,感興趣的朋友跟隨文章往下看看吧
    2022-04-04
  • Java中的輸出格式化問(wèn)題小結(jié)

    Java中的輸出格式化問(wèn)題小結(jié)

    在Java中,System.out.printf方法用于格式化輸出,格式化字符串`%.6f`表示浮點(diǎn)數(shù)保留6位小數(shù),其他格式化選項(xiàng)包括`%d`(整數(shù))、`%s`(字符串)和`%e`(科學(xué)計(jì)數(shù)法),示例代碼展示了如何使用這些格式化選項(xiàng),感興趣的朋友一起看看吧
    2025-02-02
  • 淺析Java 并發(fā)編程中的synchronized

    淺析Java 并發(fā)編程中的synchronized

    這篇文章主要介紹了Java 并發(fā)編程中的synchronized的相關(guān)資料,幫助大家更好的理解和學(xué)習(xí)Java并發(fā)編程,感興趣的朋友可以了解下
    2020-12-12
  • 深入探索Java常量池

    深入探索Java常量池

    這篇文章主要介紹了深入探索Java常量池,涉及靜態(tài)常量池和運(yùn)行時(shí)常量池的介紹,常量池的好處,8種基本數(shù)據(jù)類(lèi)型的包裝類(lèi)和常量池等相關(guān)內(nèi)容,具有一定參考價(jià)值,需要的朋友可以了解下。
    2017-11-11
  • 一文詳解Java17中LinkedList類(lèi)的用法和應(yīng)用場(chǎng)景

    一文詳解Java17中LinkedList類(lèi)的用法和應(yīng)用場(chǎng)景

    LinkedList 是 Java 集合框架中基于雙向鏈表實(shí)現(xiàn)的類(lèi),實(shí)現(xiàn)了 List 和 Deque 接口,本文將為大家介紹一下它在Java 17 中如何更高效的使用吧
    2025-03-03
  • 詳解MyBatis工作原理

    詳解MyBatis工作原理

    近來(lái)想寫(xiě)一個(gè)mybatis的分頁(yè)插件,但是在寫(xiě)插件之前肯定要了解一下mybatis具體的工作原理吧,本文就詳細(xì)總結(jié)了MyBatis工作原理,,需要的朋友可以參考下
    2021-05-05
  • Java經(jīng)典排序算法之二分插入排序詳解

    Java經(jīng)典排序算法之二分插入排序詳解

    這篇文章主要為大家詳細(xì)介紹了Java經(jīng)典排序算法之二分插入排序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-04-04
  • Java責(zé)任鏈模式定義與用法分析

    Java責(zé)任鏈模式定義與用法分析

    這篇文章主要介紹了Java責(zé)任鏈模式定義與用法,結(jié)合具體實(shí)例分析了java責(zé)任鏈模式的功能、定義、使用方法、適用情況等,需要的朋友可以參考下
    2017-06-06

最新評(píng)論