Spring工程中集成多個(gè)redis數(shù)據(jù)源的思路詳解
問(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。
參考
- Multiple Redis Connections in Spring Boot
- Spring Boot Redis CRUD Example
- The Spring @Qualifier Annotation
- Connection Modes
- 【Redis】Integration with Spring Boot
- Accessing AWS ElastiCache (Redis) from different Amazon VPC(s) via AWS PrivateLink
到此這篇關(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)題的解決
在數(shù)據(jù)庫(kù)設(shè)計(jì)中,有時(shí)候需要使用復(fù)合主鍵來(lái)唯一標(biāo)識(shí)表中的一行數(shù)據(jù),本文將為您詳細(xì)介紹MyBatis Plus中復(fù)合主鍵的問(wèn)題以及解決方案,具有一定的參考價(jià)值,感興趣的可以了解一下2023-09-09一文詳解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