Redis 多数据源自定义配置 Spring Boot 升级版

文章目录

    • 1.前言
    • 2.git 示例地址
    • 3.需求
    • 4.代码实现
      • 4.1 application.properties 配置文件
      • 4.2 获取 application.properties 中的 redis 配置
        • 4.2.1 Environment 对象来获取自定义 redis 配置
      • 4.3 初始化 RedisTemplate 对象,并注册到 Spring IOC 容器
        • 4.3.1 初始化方法
        • 4.3.2 CreateRedisTemplate 方法
        • 4.3.3 getJedisConnectionFactory 方法
      • 4.4 测试 Demo

1.前言

本文为大家提供一个 redis 配置多数据源的实现方案;为上一篇文章【Redis 多数据源 Spring Boot 实现】的升级版本

  • 支持自定义配置
  • 无需写任何其他配置 Java 类
  • application.properties 配置完,直接就可以使用

请注意 spring boot 的相关依赖版本。

2.git 示例地址

git 仓库地址:https://github.com/huajiexiewenfeng/redis-multi-spring/tree/dev-1.0

上个版本为 master 分支,本文为 dev-1.0 分支升级版本

3.需求

1.不需要每一个配置都写一个 Properties 类

2.不需要每一个配置都写一个 RedisTemplate 配置

    @Bean("oneRedisTemplate")public RedisTemplate<String, Object> oneRedisTemplate() {...}@Bean("twoRedisTemplate")public RedisTemplate<String, Object> twoRedisTemplate() {...}

3.使用方法可以与 properties 里面的配置直接对应,比如 oneRedisTemplate

    @Autowired@Qualifier("oneRedisTemplate")private RedisTemplate<String, Object> redisTemplateOne;

对应 application.properties 中的 multi.redis.one 前缀

multi.redis.one.database=${REDIS_DB_INDEX:2}
multi.redis.one.flushdb=${REDIS_FLUSHDB:false}
multi.redis.one.host=${REDIS_HOST:127.0.0.1}
multi.redis.one.port=${REDIS_PORT:6379}
multi.redis.one.password=123456

其中,multi.redis.one 前缀中的 one 为自定义字符串,可以为任意值

比如 multi.redis.csdn.database 对应的 spring bean name 为 csdnRedisTemplate

    @Autowired@Qualifier("csdnRedisTemplate")private RedisTemplate<String, Object> redisTemplateOne;

4.代码实现

4.1 application.properties 配置文件

配置文件和原版保持一致

spring.application.name=${APPLICATION_NAME:redis-multiple}
server.port=${SERVER_PORT:22216}# spring 默认配置
spring.redis.database=${REDIS_DB_INDEX:1}
spring.redis.flushdb=${REDIS_FLUSHDB:false}
spring.redis.host=${REDIS_HOST:127.0.0.1}
spring.redis.port=${REDIS_PORT:6379}
spring.redis.password=123456#第一个 redis 实例配置
multi.redis.one.database=${REDIS_DB_INDEX:2}
multi.redis.one.flushdb=${REDIS_FLUSHDB:false}
multi.redis.one.host=${REDIS_HOST:127.0.0.1}
multi.redis.one.port=${REDIS_PORT:6379}
multi.redis.one.password=123456#第二个 redis 实例配置
multi.redis.two.database=${REDIS_DB_INDEX:3}
multi.redis.two.flushdb=${REDIS_FLUSHDB:false}
multi.redis.two.host=${REDIS_HOST:127.0.0.1}
multi.redis.two.port=${REDIS_PORT:6379}
multi.redis.two.password=123456

4.2 获取 application.properties 中的 redis 配置

4.2.1 Environment 对象来获取自定义 redis 配置

实现 EnvironmentAware 接口,获取 Environment 对象,从而来获取我们自定义的配置,核心代码如下:

public class RedisMultiConfiguration implements EnvironmentAware, ApplicationContextAware {//...此处省略N行代码@Overridepublic void setEnvironment(Environment environment) {this.environment = environment;// 获取 application.properties 对应的 java 类对象PropertySource<?> propertySource = ((StandardServletEnvironment) environment).getPropertySources().get("applicationConfig: [classpath:/application.properties]");assert propertySource != null;Object source = propertySource.getSource();// 拿到 redis 配置的前缀集合,例如 multi.redis.xxx...Set<String> redisConfigKeys = new HashSet<>();if (source instanceof LinkedHashMap) {LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>) source;Set<String> keys = map.keySet();for (String key : keys) {// find multi.redis propertiesif (key.startsWith("multi.redis")) {redisConfigKeys.add(key.substring(0, StrUtils.findNthOccurrence(key, ".", 3)));}}}if (redisConfigKeys.isEmpty()) {log.error("redis config not found");}this.redisConfigKeyPrefixSet = redisConfigKeys;}@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {this.applicationContext = applicationContext;}//...此处省略N行代码
}

后续再通过 environment.getProperty(keyPrefix + "." + REDIS_CONFIG_HOST_NAME) 就可以拿到参数的值

  • keyPrefix = multi.redis.xxx…

4.3 初始化 RedisTemplate 对象,并注册到 Spring IOC 容器

4.3.1 初始化方法
@Slf4j
@Configuration
public class RedisMultiConfiguration implements EnvironmentAware, ApplicationContextAware {private Environment environment;private ApplicationContext applicationContext;private Set<String> redisConfigKeyPrefixSet = new HashSet<>();@PostConstructpublic void initConfig() {if (redisConfigKeyPrefixSet.isEmpty()) {return;}for (String keyPrefix : redisConfigKeyPrefixSet) {String key = keyPrefix.replace(MULTI_REDIS_CONFIG_PREFIX, "");// 创建自定义 RedisTemplate 对象RedisTemplate<String, Object> redisTemplate = CreateRedisTemplate(keyPrefix, environment);// 注册到 Spring IOC 容器((AnnotationConfigServletWebServerApplicationContext) applicationContext).getBeanFactory().registerSingleton(key + "RedisTemplate", redisTemplate);}}//...此处省略N行代码
}
4.3.2 CreateRedisTemplate 方法
  private RedisTemplate<String, Object> CreateRedisTemplate(String keyPrefix, Environment environment) {JedisConnectionFactory jedisConnectionFactory = this.getJedisConnectionFactory(keyPrefix, environment);RedisTemplate<String, Object> template = new RedisTemplate<>();// 设置key的序列化方式StringRedisSerializer keySerializer = new StringRedisSerializer();template.setConnectionFactory(jedisConnectionFactory);template.setKeySerializer(keySerializer);// 设置value的序列化方式Jackson2JsonRedisSerializer<Object> valueSerializer = new Jackson2JsonRedisSerializer<>(Object.class);ObjectMapper om = new ObjectMapper();// 指定要序列化的域,field,get和set,以及修饰符范围,ANY是无论什么都可以序列化om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);// 启用DefaultTyping,方便我们反序列化时知道对象的类型om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);valueSerializer.setObjectMapper(om);template.setValueSerializer(valueSerializer);// 设置Hash的key和value序列化方式template.setHashKeySerializer(keySerializer);template.setHashValueSerializer(valueSerializer);// 设置value的泛型类型,这样在存取的时候才会序列化和反序列化成设置的对象类型// 注意:这里只是设置了value的泛型,key还是String类型template.afterPropertiesSet();return template;}
4.3.3 getJedisConnectionFactory 方法

通过前缀+ environment 去获取对应的配置,再设置到 JedisConnectionFactory 中。

    private JedisConnectionFactory getJedisConnectionFactory(String keyPrefix, Environment environment) {JedisPoolConfig poolConfig = new JedisPoolConfig();// 设置连接池参数,例如最大连接数、最大空闲连接数等poolConfig.setMaxTotal(100);poolConfig.setMaxIdle(30);poolConfig.setMinIdle(10);JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(poolConfig);jedisConnectionFactory.setHostName(StrUtils.ifEmpty(environment.getProperty(keyPrefix + "." + REDIS_CONFIG_HOST_NAME), "127.0.0.1"));jedisConnectionFactory.setPort(Integer.parseInt(StrUtils.ifEmpty(environment.getProperty(keyPrefix + "." + REDIS_CONFIG_PORT_NAME), "6379")));jedisConnectionFactory.setDatabase(Integer.parseInt(StrUtils.ifEmpty(environment.getProperty(keyPrefix + "." + REDIS_CONFIG_DATABASE_NAME), "1")));jedisConnectionFactory.setPassword(StrUtils.ifEmpty(environment.getProperty(keyPrefix + "." + REDIS_CONFIG_PASSWORD_NAME), "123456"));jedisConnectionFactory.afterPropertiesSet();return jedisConnectionFactory;}

4.4 测试 Demo

@RestController
public class TestController {@Autowiredprivate RedisTemplate<String,String> redisTemplate;@Autowired@Qualifier("oneRedisTemplate")private RedisTemplate<String, Object> redisTemplateOne;@Autowired@Qualifier("twoRedisTemplate")private RedisTemplate<String, Object> redisTemplateTwo;@GetMapping("/test/redis/add")public void profileDetails() {redisTemplate.opsForValue().set("test1-dev1.0", "1");redisTemplateOne.opsForValue().set("test2-dev1.0", 2);redisTemplateTwo.opsForValue().set("test3-dev1.0", 3);}}

浏览器输入

http://127.0.0.1:22216/test/redis/add

执行结果如下:

db1

请添加图片描述

db2

请添加图片描述

db3

请添加图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/369279.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring boot (shiro)+ websocket测试连接不上的简单检测处理

1、用前端连接测试的demo一切正常&#xff0c;但是到了项目中连接不上了 一开始以为是地址错&#xff0c;但是换了apifox测试也是不可以。 2、考虑是shiro进行了拦截了&#xff0c;所以就访问不到了地址&#xff0c;那么就放行。 3、再次用apifox测试&#xff0c;成功了。 当然…

马拉松报名小程序的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;赛事信息管理&#xff0c;赛事报名管理&#xff0c;活动商城管理&#xff0c;留言板管理&#xff0c;系统管理 微信端账号功能包括&#xff1a;系统首页&#xff0c;赛事信息&…

C++:智能指针

目录 前言 1.内存泄漏及其危害 2.内存泄漏分类&#xff1a; 3.如何检测内存泄漏 4.如何避免内存泄漏 一、为什么需要智能指针&#xff1f; 二、智能指针的使用及其原理 1.RAII 2.智能指针 3.std::auto_ptr 4.std::unique_ptr 5.std::shared_ptr 6.std::weak_ptr…

SA 注册流程

目录 1. UE开机后按照3GPP TS 38.104定义的Synchronization Raster搜索特定频点 2.UE尝试检测PSS/SSS&#xff0c;取得下行时钟同步&#xff0c;并获取小区的PCI&#xff1b;如果失败则转步骤1搜索下一个频点&#xff1b;否则继续后续步骤&#xff1b; 3.解析Mib&#xff0c;…

从0到1构建渠道运营体系:实战案例与策略指南

引言 在当今竞争激烈的市场环境中&#xff0c;有效的渠道运营是企业实现产品或服务快速触达目标用户、提升市场份额的关键。从零开始构建一个高效的渠道运营体系&#xff0c;不仅需要深思熟虑的策略规划&#xff0c;还需要灵活应变的实战操作。本文将结合实战案例&#xff0c;…

JDK新特性之协程

在 JVM 中&#xff0c;java 线程直接映射内核线程&#xff0c;因此 java 线程的创建、销毁和调度都要依赖内核态的操作&#xff08;系统调用&#xff09;。而协程是真正的用户线程&#xff0c;如上图所示很多的协程可以映射很少的几个内核线程&#xff0c;并且协程的创建、销毁…

gitee代码初次上传步骤

ps. 前提是已经下载安装gitee 一、在本地项目目录下空白处右击&#xff0c;选择“Git Bash Here” 二、初始化 git init 三、添加、提交代码&#xff08;注意add与点之间的空格&#xff09; git add . git commit -m 添加注释 四、连接、推送到gitee仓库 git remote add …

Renderless 思想正在影响前端开发

本文由前端小伙伴方长_beezen 原创。欢迎大家踊跃投稿。 原文链接&#xff1a;https://juejin.cn/post/7385752495535472655 前言 截止到 2024 年&#xff0c;跨端应用开发所需要考虑的兼容性&#xff0c;已经涵盖了框架、平台和设备类型等多个方面&#xff0c;例如&#xff1…

「ETL趋势」分区支持PostgreSQL、Greenplum、Gauss200, 定时任务支持Kettle

FineDataLink作为一款市场上的顶尖ETL工具&#xff0c;集实时数据同步、ELT/ETL数据处理、数据服务和系统管理于一体的数据集成工具&#xff0c;进行了新的维护迭代。本文把FDL4.1.9最新功能作了介绍&#xff0c;方便大家对比&#xff1a;&#xff08;产品更新详情&#xff1a;…

MYSQL篇二:数据库的操作

文章目录 1. 创建数据库1.1 查看数据库列表1.2 创建与删除数据库 2. 数据的编码问题3. 字符集和校验规则3.1 查看系统默认字符集以及校验规则3.2 查看数据库支持的字符集3.3 查看数据库支持的字符集校验规则3.4 校验规则对数据库的影响 4. 操纵数据库4.1 查看当前是哪一个数据库…

安装docker compose与elasticsearch,kibana

1.docker compose安装 1.1是否已安装docker docker -v 1.2安装docker compose curl -SL https://github.com/docker/compose/releases/download/v2.18.0/docker-compose-linux-x86_64 -o /usr/local/bin/docker-composeps:如果网络太慢可直接在博客中下载附属文件 下载后修…

【二】Ubuntu24虚拟机在Mac OS的VMware Fusion下无法联网问题

文章目录 1.环境背景2. 需求背景3. 解决方法3.1 在mac的终端查看虚拟机NAT网络3.2 查看unbuntu节点2的网络配置3.3 问题定位与解决3.3.1 检查是否有冲突3.3.2 冲突解决方法 4. 总结4.1 NAT 网关的原理4.2 VMware Fusion 的 NAT 模式4.3 为什么网关冲突会引起问题4.4 理解配置冲…

python作业一

1. #A.方法一 num int(input("请输入要打印的层数:")) for n in range(1, num1):s ""for i in range(1, n1):s f"{i}" " "print(s) #方法二&#xff1a; iint(input("i:")) for i in range(1,i1):s""for j i…

JavaSE (Java基础):面向对象(下)

8.7 多态 什么是多态&#xff1f; 即同一方法可以根据发送对象的不同而采用多种不同的方式。 一个对象的实际类型是确定的&#xff0c;但可以指向对象的引用的类型有很多。在句话我是这样理解的&#xff1a; 在实例中使用方法都是根据他最开始将类实例化最左边的类型来定的&…

uni-app 自定义支付密码键盘

1.新建组件 payKeyboard .vue <template><view class"page-total" v-show"isShow"><view class"key-list"><view class"list" v-for"(item,index) in keyList" :class"{special:item.keyCode190…

文件操作及部分文件函数的介绍学习(上)

目录 前言 1.为什么要要使用文件&#xff1f; 2.什么是文件&#xff1f; 2.1程序文件 2.2数据文件 2.3文件名 4.文件的打开和关闭 4.1 流和标准流 4.1.1流 4.1.2标准流 4.2文件指针 4.3文件的打开和关闭 结语 前言 Hello&#xff0c;亲爱的小伙伴们&#xff0c;作…

游戏AI的创造思路-技术基础-计算机视觉

让游戏的AI具备“眼睛”和“视觉”&#xff0c;就是通过计算机视觉的方法进行的。现在&#xff0c;越来越多的游戏&#xff0c;特别是动捕类游戏都在使用这个方法。当然&#xff0c;计算机视觉不仅仅用于游戏&#xff0c;越来越多的应用使用到这个技术 目录 1. 定义 2. 发展历…

电气-伺服(6)脉冲控制

一、脉冲模式原理&#xff1a; 运动控制器输出脉冲信号给伺服驱动器 伺服驱动器工作于位置模式 伺服驱动器内部要完成三闭环&#xff08;位置闭环 、速度闭环、电流环&#xff09; 脉冲和伺服控制环&#xff1a;脉冲的个数作用于位置环。脉冲的频率作用于速度环 二、脉冲的两…

【高性能服务器】select模型

&#x1f525;博客主页&#xff1a; 我要成为C领域大神&#x1f3a5;系列专栏&#xff1a;【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 IO多路复用就是复用…

Debug-017-elementUI-el-cascader组件首次选择选项不触发表单的自定义校验

前情提要&#xff1a; 今天维护一个表单校验的时候发现一件事情&#xff0c;就是在表单中使用了 el-cascader组件&#xff0c;希望根据接口返回数据去动态校验一下这里面的选项&#xff0c;符合逻辑就通过自定义的表单校验&#xff0c;不符合就在这一项的下面标红提示。做的时候…