当前位置: 首页 > news >正文

Spring工程中集成多个redis数据源

问题

有个项目需要在同一个Spring工程中集成2个redis数据源。

思路

配置2个redis连接工厂,再配置2个redistemplate。然后,在使用缓存的时候,分别注入不同的redistemplate解决这个问题。这里主要是使用了spring中的2个注释:

  • @Primary:设置默认bean
  • @Qualifier:指定注入bean

解决

FhRedisConfig.java

这个类是配置第2个多余的redis,对application.yml文件中自定义redis配置映射类。如果application.yml文件中有如下配置:

fh:redis:host: 12.86.12.9password: swdghopport: 6379database:7	

这对应配置类如下:

package com.xxxx.framework.config;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;/*** redis配置类*/
@Data
@ConfigurationProperties(prefix = "fh.redis")
public class FhRedisConfig {/*** 主机地址*/private String host;/*** 密码*/private String password;/*** Redis 服务器端口号* 默认值:6379(Redis 默认端口)*/private int port = 6381;/*** Redis 数据库索引(0-15)* 默认值:0*/private int database = 0;}

RedisConfig.java

这是redis配置类,这里主要配置2个redis连接工厂,2个redistemplate的bean。而且,使用@Primary设置redistemplate类注入的默认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
{@Resourceprivate FhRedisConfig fhRedisConfig;@Value("${spring.profiles.active:default}")private String activeProfile;/*** 默认redis连接池* @return 默认redis连接池*/@Bean@Primarypublic 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连接池*/@Beanpublic RedisConnectionFactory fhRedisConnectionFactory(RedisProperties redisProperties) {return getRedisConnectionFactory(redisProperties, fhRedisConfig.getHost(), fhRedisConfig.getPort(), fhRedisConfig.getPassword(),fhRedisConfig.getDatabase(), null);}/*** redis客户端* @param connectionFactory redis连接池* @return redis客户端*/@Beanpublic RedisTemplate<Object, Object> fhRedisTemplate(@Qualifier("fhRedisConnectionFactory")RedisConnectionFactory connectionFactory){return getRedisTemplate(connectionFactory);}/*** 默认redis客户端* @param connectionFactory 默认redis连接池* @return 默认redis客户端*/@Bean@Primarypublic 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;// 根据是否是集群模式选择不同的配置if (!CollectionUtils.isEmpty(nodes)) {// 配置集群拓扑刷新选项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)  // 关键:设置连接池.commandTimeout(redisProperties.getTimeout()).useSsl();if (!activeProfile.equals("prod")) {lettucePoolingSslClientConfigurationBuilder.disablePeerVerification();}LettucePoolingClientConfiguration poolingClientConfig = lettucePoolingSslClientConfigurationBuilder.build();// 创建集群配置RedisClusterConfiguration clusterConfig = new RedisClusterConfiguration(nodes);clusterConfig.setPassword(password);// 创建 LettuceConnectionFactorylettuceConnectionFactory = new LettuceConnectionFactory(clusterConfig, poolingClientConfig);} else {// 非集群模式保持原逻辑GenericObjectPoolConfig<?> poolConfig = getGenericObjectPoolConfig(redisProperties);LettucePoolingClientConfiguration.LettucePoolingSslClientConfigurationBuilder lettucePoolingSslClientConfigurationBuilder = LettucePoolingClientConfiguration.builder().poolConfig(poolConfig)  // 关键:设置连接池.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-activepoolConfig.setMaxIdle(poolProps.getMaxIdle());        // max-idlepoolConfig.setMinIdle(poolProps.getMinIdle());        // min-idlepoolConfig.setMaxWaitMillis(poolProps.getMaxWait().toMillis());        // max-wait}return poolConfig;}
}

注意@Qualifier注释的使用,这里使用指定了特定的redis连接工厂。下面的在业务代码中注入redistemaplte的时候,也需要使用呢@Qualifier注释来使用特定的redis集群。

Controller.java

这是业务代码中,注入使用特定的redis集群,如下代码:

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

如果不需要使用特定redis,只需要使用默认redis则不需要@Qualifier注释,如下:

@Resource
public RedisTemplate redisTemplate;

总结

这就是Spring项目redis多数据源问题。主要就是通过@Primary注释来配置默认bean,通过@Qualifier注释来指定使用的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
http://www.dtcms.com/a/295282.html

相关文章:

  • iOS WebView 加载失败与缓存刷新问题排查实战指南
  • [iOS开发工具] 【iOS14以及以下】cydia商店按键精灵iOS新版V2.X安装教程
  • STM32 IAP升级失败之谜:时钟源配置的陷阱与解决方案
  • 【AJAX】XMLHttpRequest、Promise 与 axios的关系
  • JAVA图文短视频交友+自营商城系统源码支持小程序+Android+IOS+H5
  • 【计算机网络】第六章:应用层
  • socket请求
  • 第二十章 W55MH32 WOL示例
  • B站 XMCVE Pwn入门课程学习笔记(5)
  • windows11通过wsl安装Ubuntu到D盘,安装docker及宝塔面板
  • 如何彻底清除服务器上的恶意软件与后门
  • 基础入门 [CMD] Windows SSH 连接服务器教程(系统自带方式)
  • Linux 下在线安装启动VNC
  • TCP 套接字--服务器相关
  • 杰理通用MCU串口+AT指令+485通讯工业语音芯片
  • PostgreSQL 跨库查询方法
  • Apache Flink 实时流处理性能优化实践指南
  • uniapp写app做测试手机通知栏展示内容
  • uni-appDay02
  • 从零用java实现 小红书 springboot vue uniapp(14) 集成阿里云短信验证码
  • 复盘—MySQL触发器实现监听数据表值的变化,对其他数据表做更新
  • 图片查重从设计到实现(2)Milvus安装准备etcd介绍、应用场景及Docker安装配置
  • 算法竞赛阶段二-数据结构(34)数据结构链表STL vector
  • 数据结构-4(常用排序算法、二分查找)
  • ​​GOFLY LIVE CHAT:Golang製オープンソース・ライブチャットシステム​
  • PHP文件下载
  • 嵌入式学习-(李宏毅)机器学习(2)-day29
  • 天线增益方向图是怎么绘制的?
  • 【ROS1】09-ROS通信机制——参数服务器
  • JavaSE:学习输入输出编写简单的程序