redisson-spring-boot-starter 自动化配置源码解析

版本

redisson-spring-boot-starter:3.25.2

此starter会自动注册RedissonClient Bean
并可通过注册RedissonAutoConfigurationCustomizer Bean实现配置自定义

 @BeanRedissonAutoConfigurationCustomizer jdkCodecCustomizer() {return configuration->{// 使用JDK序列化器configuration.setCodec(new SerializationCodec());};}

源码

spring-boot:2.7以上
org.redisson.spring.starter.RedissonAutoConfigurationV2

@AutoConfiguration(before = RedisAutoConfiguration.class)
@ConditionalOnClass({Redisson.class, RedisOperations.class})
@EnableConfigurationProperties({RedissonProperties.class, RedisProperties.class}) // 启用spring.data.redis,spring.redisson配置属性
public class RedissonAutoConfigurationV2 extends RedissonAutoConfiguration {
}

spring-boot:2.6以下
org.redisson.spring.starter.RedissonAutoConfiguration

@Configuration
@ConditionalOnClass({Redisson.class, RedisOperations.class})
// 防止spring-boot:2.7以上版本时跟RedissonAutoConfigurationV2冲突
@ConditionalOnMissingClass("org.springframework.boot.autoconfigure.AutoConfiguration") 
@AutoConfigureBefore(RedisAutoConfiguration.class)
@EnableConfigurationProperties({RedissonProperties.class, RedisProperties.class})
public class RedissonAutoConfiguration {...// 注册RedissonClient @Bean(destroyMethod = "shutdown")@ConditionalOnMissingBean(RedissonClient.class)public RedissonClient redisson() throws IOException {Config config;Method clusterMethod = ReflectionUtils.findMethod(RedisProperties.class, "getCluster");Method usernameMethod = ReflectionUtils.findMethod(RedisProperties.class, "getUsername");Method timeoutMethod = ReflectionUtils.findMethod(RedisProperties.class, "getTimeout");Method connectTimeoutMethod = ReflectionUtils.findMethod(RedisProperties.class, "getConnectTimeout");Method clientNameMethod = ReflectionUtils.findMethod(RedisProperties.class, "getClientName");Object timeoutValue = ReflectionUtils.invokeMethod(timeoutMethod, redisProperties);String prefix = getPrefix();String username = null;int database = redisProperties.getDatabase();String password = redisProperties.getPassword();boolean isSentinel = false;boolean isCluster = false;// 如果存在redis连接详细配置,则从详细配置中获取用户名,密码,哨兵模式标识,集群模式标识if (hasConnectionDetails()) {ObjectProvider<RedisConnectionDetails> provider = ctx.getBeanProvider(RedisConnectionDetails.class);RedisConnectionDetails b = provider.getIfAvailable();if (b != null) {password = b.getPassword();username = b.getUsername();if (b.getSentinel() != null) {isSentinel = true;}if (b.getCluster() != null) {isCluster = true;}}}// 获取redis配置中的超时时间Integer timeout = null;if (timeoutValue instanceof Duration) {timeout = (int) ((Duration) timeoutValue).toMillis();} else if (timeoutValue != null){timeout = (Integer)timeoutValue;}// 获取redis配置中的连接超时时间Integer connectTimeout = null;if (connectTimeoutMethod != null) {Object connectTimeoutValue = ReflectionUtils.invokeMethod(connectTimeoutMethod, redisProperties);if (connectTimeoutValue != null) {connectTimeout = (int) ((Duration) connectTimeoutValue).toMillis();}} else {connectTimeout = timeout;}// 获取redis配置中的客户端名称String clientName = null;if (clientNameMethod != null) {clientName = (String) ReflectionUtils.invokeMethod(clientNameMethod, redisProperties);}// 获取redis配置中的用户名if (usernameMethod != null) {username = (String) ReflectionUtils.invokeMethod(usernameMethod, redisProperties);}if (redissonProperties.getConfig() != null) {// 如果存在redisson配置(在application.yml中以字符串形式配置)try {// 尝试解析yml格式配置字符串config = Config.fromYAML(redissonProperties.getConfig());} catch (IOException e) {try {// 尝试解析json格式配置字符串config = Config.fromJSON(redissonProperties.getConfig());} catch (IOException e1) {e1.addSuppressed(e);throw new IllegalArgumentException("Can't parse config", e1);}}} else if (redissonProperties.getFile() != null) {// 如果存在redisson配置文件(yml或json)try {InputStream is = getConfigStream();config = Config.fromYAML(is);} catch (IOException e) {// trying next formattry {InputStream is = getConfigStream();config = Config.fromJSON(is);} catch (IOException e1) {e1.addSuppressed(e);throw new IllegalArgumentException("Can't parse config", e1);}}} else if (redisProperties.getSentinel() != null || isSentinel) {// 连接哨兵模式集群String[] nodes = {};String sentinelMaster = null;if (redisProperties.getSentinel() != null) {Method nodesMethod = ReflectionUtils.findMethod(Sentinel.class, "getNodes");Object nodesValue = ReflectionUtils.invokeMethod(nodesMethod, redisProperties.getSentinel());if (nodesValue instanceof String) {nodes = convert(prefix, Arrays.asList(((String)nodesValue).split(",")));} else {nodes = convert(prefix, (List<String>)nodesValue);}sentinelMaster = redisProperties.getSentinel().getMaster();}String sentinelUsername = null;String sentinelPassword = null;if (hasConnectionDetails()) {ObjectProvider<RedisConnectionDetails> provider = ctx.getBeanProvider(RedisConnectionDetails.class);RedisConnectionDetails b = provider.getIfAvailable();if (b != null && b.getSentinel() != null) {database = b.getSentinel().getDatabase();sentinelMaster = b.getSentinel().getMaster();nodes = convertNodes(prefix, (List<Object>) (Object) b.getSentinel().getNodes());sentinelUsername = b.getSentinel().getUsername();sentinelPassword = b.getSentinel().getPassword();}}config = new Config();SentinelServersConfig c = config.useSentinelServers().setMasterName(sentinelMaster).addSentinelAddress(nodes).setSentinelPassword(sentinelPassword).setSentinelUsername(sentinelUsername).setDatabase(database).setUsername(username).setPassword(password).setClientName(clientName);if (connectTimeout != null) {c.setConnectTimeout(connectTimeout);}if (connectTimeoutMethod != null && timeout != null) {c.setTimeout(timeout);}initSSL(c);} else if ((clusterMethod != null && ReflectionUtils.invokeMethod(clusterMethod, redisProperties) != null)|| isCluster) {// 连接分片集群String[] nodes = {};if (clusterMethod != null && ReflectionUtils.invokeMethod(clusterMethod, redisProperties) != null) {Object clusterObject = ReflectionUtils.invokeMethod(clusterMethod, redisProperties);Method nodesMethod = ReflectionUtils.findMethod(clusterObject.getClass(), "getNodes");List<String> nodesObject = (List) ReflectionUtils.invokeMethod(nodesMethod, clusterObject);nodes = convert(prefix, nodesObject);}if (hasConnectionDetails()) {ObjectProvider<RedisConnectionDetails> provider = ctx.getBeanProvider(RedisConnectionDetails.class);RedisConnectionDetails b = provider.getIfAvailable();if (b != null && b.getCluster() != null) {nodes = convertNodes(prefix, (List<Object>) (Object) b.getCluster().getNodes());}}config = new Config();ClusterServersConfig c = config.useClusterServers().addNodeAddress(nodes).setUsername(username).setPassword(password).setClientName(clientName);if (connectTimeout != null) {c.setConnectTimeout(connectTimeout);}if (connectTimeoutMethod != null && timeout != null) {c.setTimeout(timeout);}initSSL(c);} else {// 连接单实例config = new Config();String singleAddr = prefix + redisProperties.getHost() + ":" + redisProperties.getPort();if (hasConnectionDetails()) {ObjectProvider<RedisConnectionDetails> provider = ctx.getBeanProvider(RedisConnectionDetails.class);RedisConnectionDetails b = provider.getIfAvailable();if (b != null && b.getStandalone() != null) {database = b.getStandalone().getDatabase();singleAddr = prefix + b.getStandalone().getHost() + ":" + b.getStandalone().getPort();}}SingleServerConfig c = config.useSingleServer().setAddress(singleAddr).setDatabase(database).setUsername(username).setPassword(password).setClientName(clientName);if (connectTimeout != null) {c.setConnectTimeout(connectTimeout);}if (connectTimeoutMethod != null && timeout != null) {c.setTimeout(timeout);}initSSL(c);}// 应用自定义配置beanif (redissonAutoConfigurationCustomizers != null) {for (RedissonAutoConfigurationCustomizer customizer : redissonAutoConfigurationCustomizers) {customizer.customize(config);}}return Redisson.create(config);}private void initSSL(BaseConfig<?> config) {Method getSSLMethod = ReflectionUtils.findMethod(RedisProperties.class, "getSsl");if (getSSLMethod == null) {return;}RedisProperties.Ssl ssl = redisProperties.getSsl();if (ssl.getBundle() == null) {return;}ObjectProvider<SslBundles> provider = ctx.getBeanProvider(SslBundles.class);SslBundles bundles = provider.getIfAvailable();if (bundles == null) {return;}SslBundle b = bundles.getBundle(ssl.getBundle());if (b == null) {return;}config.setSslCiphers(b.getOptions().getCiphers());config.setSslProtocols(b.getOptions().getEnabledProtocols());config.setSslTrustManagerFactory(b.getManagers().getTrustManagerFactory());config.setSslKeyManagerFactory(b.getManagers().getKeyManagerFactory());}
}

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

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

相关文章

Hadoop详解

Hadoop 概念 就是一个大数据解决方案。它提供了一套分布式系统基础架构。 核心内容包含 hdfs 和mapreduce。hadoop2.0 以后引入 yarn. hdfs 是提供数据存储的&#xff0c;mapreduce 是方便数据计算的。 hdfs 又对应 namenode 和 datanode. namenode 负责保存元数据的基本信息…

移动端自适应解决方法(adaptive插件,原理是rem布局)

点击跳转官方Git地址 此博客参考笔记 也可以直接复制下方的js文件直接使用 index.js var adaptive {}; (function (win, lib) {var doc win.document;var docEl doc.documentElement;// 设备像素比var devicePixelRatio win.devicePixelRatio;// 我们设置的布局视口与理…

docker使用Dockerfile制做容器(以hyperf为列,开机启动)

1、Dockerfile文件 FROM hyperf/hyperf:8.1-alpine-v3.18-swoole WORKDIR /data MAINTAINER dade <dadeqq.com> ADD start.sh start.sh RUN chmod x ./start.sh CMD /data/start.sh1-1、执行命令生成hyperf:latest容器&#xff08;文件名是Dockerfile可以省略&#xff0…

YZ系列工具之YZ04:文本批量替换使用说明文档

我给VBA下的定义&#xff1a;VBA是个人小型自动化处理的有效工具。利用好了&#xff0c;可以大大提高自己的工作效率&#xff0c;而且可以提高数据的准确度。我的教程一共九套一部VBA手册&#xff0c;教程分为初级、中级、高级三大部分。是对VBA的系统讲解&#xff0c;从简单的…

解锁新身份:无忧秘书智脑-AI智能直播的10宫格姓氏头像制作秘籍

在这个信息爆炸的时代&#xff0c;一个独特的标识是个人或品牌在众多竞争者中脱颖而出的关键。而头像作为我们日常在线身份的一部分&#xff0c;更是我们展示个性和风格的重要窗口。无忧秘书智脑-AI智能直播最新推出的专属姓氏10宫格头像功能&#xff08;ai6ai69)&#xff0c;为…

【Python学习】Python学习21- 正则表达式(2)

目录 【Python学习】Python学习21- 正则表达式&#xff08;2&#xff09; 前言字符串检索和替换repl 参数是一个函数参考 文章所属专区 Python学习 前言 本章节主要说明Python的正则表达式。 正则表达式是一个特殊的字符序列&#xff0c;它能帮助你方便的检查一个字符串是否与…

MySQL缓冲池(Buffer Pool)深入解析:原理、组成及其在数据操作中的核心作用

在关系型数据库管理系统&#xff08;RDBMS&#xff09;中&#xff0c;性能优化一直是数据库管理员和开发者关注的焦点。作为最流行的开源RDBMS之一&#xff0c;MySQL提供了多种优化手段&#xff0c;其中InnoDB存储引擎的缓冲池&#xff08;Buffer Pool&#xff09;是最为关键的…

小埋公司的IPO方案的题解

目录 原题描述&#xff1a; 题目描述 输入格式 输出格式 输出格式 样例 #1 样例输入 #1 样例输出 #1 样例 #2 样例输入 #2 样例输出 #2 提示 题目大意&#xff1a; 主要思路&#xff1a; 但是but 代码code&#xff1a; 时间限制: 500ms 空间限制: 65536kB 原题…

pytest 参数化测试用例构建

在之前的文章中主要分享了 pytest 的实用特性&#xff0c;接下来讲 Pytest 参数化用例的构建。 如果待测试的输入与输出是一组数据&#xff0c;可以把测试数据组织起来用不同的测试数据调用相同的测试方法。参数化顾名思义就是把不同的参数&#xff0c;写到一个集合里&#xf…

Apipost智能Mock教程

在接口开发过程中&#xff0c;Mock功能可以帮助开发者快速测试和验证接口的正确性和稳定性&#xff0c;以便快速迭代和修复问题。Apipost推出智能Mock功能&#xff0c;可以在智能期望中填写一些触发条件&#xff0c;开启后&#xff0c;Apipost会根据已设置的触发条件&#xff0…

自定义服务自启动失败

如果你已经使用 systemctl enable postgres.service 启用了服务的自启动&#xff0c;但重启后服务没有自动启动&#xff0c;可能有几种原因&#xff1a; 启动顺序问题&#xff1a; 如果 PostgreSQL 服务依赖于其他服务&#xff0c;可能在其依赖项启动之前尝试启动。你可以通过…

大创项目推荐 疫情数据分析与3D可视化 - python 大数据

文章目录 0 前言1 课题背景2 实现效果3 设计原理4 部分代码5 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 大数据全国疫情数据分析与3D可视化 该项目较为新颖&#xff0c;适合作为竞赛课题方向&#xff0c;学长非常推荐&#xff0…

力扣70. 爬楼梯(动态规划 Java,C++解法)

Problem: 70. 爬楼梯 文章目录 题目描述思路解题方法复杂度Code 题目描述 思路 由于本题目中第i层台阶只能由于第i- 1层台阶和第i-2层台阶走来&#xff0c;所以可以联想到动态规划&#xff0c;具体如下&#xff1a; 1.定义多阶段决策模型&#xff1a;对于每一上台阶看作一种状…

zookeeper window 安装

下载 Apache ZooKeeper 解压Zookeeper安装包到指定目录&#xff0c;注意目录不要有空格。 备份zoo_sample.cfg并改名zoo.cfg 注意&#xff1a;此处的路径一定要使用双斜杠" \\ " D:\\apache-zookeeper-3.8.3-bin\\data 新建环境变量&#xff1a;ZOOKEEPER_HOME D…

jQuery隐藏 显示 —— W3school 详解 简单易懂(四)

jQuery 效果 - 隐藏和显示 jQuery 事件jQuery 淡入淡出 隐藏、显示、切换&#xff0c;滑动&#xff0c;淡入淡出&#xff0c;以及动画&#xff0c;哇哦&#xff01; 实例 jQuery hide() 演示一个简单的 jQuery hide() 方法。 jQuery hide() 另一个 hide() 演示。如何隐藏…

如何利用chatgpt提升工作效率?教你chatGTP怎么提高效率

如何利用chatgpt提升工作效率&#xff1f;教你chatGTP怎么提高效率 在当今信息时代&#xff0c;人们的工作需要处理的信息量越来越大&#xff0c;而随着人工智能技术的不断发展&#xff0c;越来越多的企业开始应用生成式AI系统ChatGPT来提高工作效率。下面介绍如何利用ChatGPT来…

鸿蒙原生应用/元服务开发-延迟任务说明(一)

一、功能介绍 应用退至后台后&#xff0c;需要执行实时性要求不高的任务&#xff0c;例如有网络时不定期主动获取邮件等&#xff0c;可以使用延迟任务。当应用满足设定条件&#xff08;包括网络类型、充电类型、存储状态、电池状态、定时状态等&#xff09;时&#xff0c;将任务…

【⭐AI工具⭐】实用工具推荐

目录 壹 实用工具工具合集TinyWowHiPDF 公式处理SimpleTex公式中常用的希腊字母符号公式在论文中的格式 图像处理BgRemoverPix Fix像素蒸发Photopea 音频处理啦啦爱 笔记整理飞书妙记 素材整理Eagle 其它一次性临时电子邮件近邻词汇检索据意查句诗三百能不能好好说话&#xff1…

PaddleDetection学习3——使用Paddle-Lite在 Android 上部署PicoDet模型(fp16)

使用Paddle-Lite在 Android 上运行PicoDet模型&#xff08;fp16&#xff09; 1. 环境准备2. 部署步骤2.1 下载Paddle-Lite-Demo2.2 打开 picodet_detection_demo项目2.2.1 修改build.gradle&#xff0c;配置国内镜像仓库2.2.2 NDK 配置错误问题2.2.3 gradle.properties文件配置…

【Python机器学习】无监督学习(理论知识)

无监督学习包括没有已知输出、没有“老师指导”学习算法的各种机器学习。在无监督学习中&#xff0c;学习算法只有输入数据&#xff0c;并需要从这些数据中提取知识。 数据集的无监督变换是创建数据新的表示的算法&#xff0c;与数据的原始表示相比&#xff0c;新的表示可能更容…