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

SpringBoot之RedisTemplate基本配置

公司要求redis配置密码使用密文,但是程序使用的是spring默认的redisTemplate,那么就需要修改配置实现密码加解密。
先搞个加密工具类:

public class SM2Encryptor {// 加密,使用公钥public static String encryptText(String publicKey, String originalText) throws Exception {//...为null判断return Sm2.doEncrypt(originalText, publicKey);}//解密,使用私钥public static String decryptText(String privateKey, String cipherText) throws Exception {//...为null判断return Sm2.doDecrypt(cipherText, privateKey);}// 生成密钥对方法//...
}

1. Redis默认配置

最简单的使用其实开箱即可用,添加依赖

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

本机启动redis,一切采用默认的配置 (host:127.0.0.1, port:6379, 无密码)

然后就可以直接注入redisTemplate实例,进行各种读写操作

@SpringBootApplication
public class Application {public Application(RedisTemplate<String, String> redisTemplate) {redisTemplate.opsForValue().set("hello", "world");String ans = redisTemplate.opsForValue().get("hello");Assert.isTrue("world".equals(ans));}public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

2. 自定义配置参数

前面是默认的配置参数,在实际的使用中,一般都会修改这些默认的配置项,如果我的应用中,只有一个redis,那么完全可以只修改默认的配置参数
修改配置文件: application.yml

spring:redis:host: 127.0.0.1port: 6379password:database: 0lettuce:pool:max-active: 32max-wait: 300msmax-idle: 16min-idle: 8

使用和前面没有什么区别,直接通过注入RedisTemplate来操作即可,需要额外注意的是设置了连接池的相关参数,需要额外引入依赖

<dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId>
</dependency>

3. 多redis配置

依赖多个不同的redis,也就是说我的项目需要从多个redis实例中获取数据,这种时候,就不能直接使用默认的,需要我们自己来声明ConnectionFactoryRedisTemplate

spring:redis:host: 127.0.0.1port: 6379password:lettuce:pool:max-active: 32max-wait: 300max-idle: 16min-idle: 8database: 0local-redis:host: 127.0.0.1port: 6379database: 0password:lettuce:pool:max-active: 16max-wait: 100max-idle: 8min-idle: 4

对应的配置类,采用Lettuce,基本设置如下,套路都差不多,先读取配置,初始化ConnectionFactory,然后创建RedisTemplate实例,设置连接工厂

@Configuration
public class RedisAutoConfig {@Beanpublic LettuceConnectionFactory defaultLettuceConnectionFactory(RedisStandaloneConfiguration defaultRedisConfig,GenericObjectPoolConfig defaultPoolConfig) {LettuceClientConfiguration clientConfig =LettucePoolingClientConfiguration.builder().commandTimeout(Duration.ofMillis(100)).poolConfig(defaultPoolConfig).build();return new LettuceConnectionFactory(defaultRedisConfig, clientConfig);}@Beanpublic RedisTemplate<String, String> defaultRedisTemplate(LettuceConnectionFactory defaultLettuceConnectionFactory) {RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(defaultLettuceConnectionFactory);redisTemplate.afterPropertiesSet();return redisTemplate;}@Bean@ConditionalOnBean(name = "localRedisConfig")public LettuceConnectionFactory localLettuceConnectionFactory(RedisStandaloneConfiguration localRedisConfig,GenericObjectPoolConfig localPoolConfig) {LettuceClientConfiguration clientConfig =LettucePoolingClientConfiguration.builder().commandTimeout(Duration.ofMillis(100)).poolConfig(localPoolConfig).build();return new LettuceConnectionFactory(localRedisConfig, clientConfig);}@Bean@ConditionalOnBean(name = "localLettuceConnectionFactory")public RedisTemplate<String, String> localRedisTemplate(LettuceConnectionFactory localLettuceConnectionFactory) {RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();redisTemplate.setConnectionFactory(localLettuceConnectionFactory);redisTemplate.afterPropertiesSet();return redisTemplate;}@Configuration@ConditionalOnProperty(name = "host", prefix = "spring.local-redis")public static class LocalRedisConfig {@Value("${spring.local-redis.host:127.0.0.1}")private String host;@Value("${spring.local-redis.port:6379}")private Integer port;@Value("${spring.local-redis.password:}")private String password;@Value("${spring.local-redis.database:0}")private Integer database;@Value("${spring.local-redis.lettuce.pool.max-active:8}")private Integer maxActive;@Value("${spring.local-redis.lettuce.pool.max-idle:8}")private Integer maxIdle;@Value("${spring.local-redis.lettuce.pool.max-wait:-1}")private Long maxWait;@Value("${spring.local-redis.lettuce.pool.min-idle:0}")private Integer minIdle;@Beanpublic GenericObjectPoolConfig localPoolConfig() {GenericObjectPoolConfig config = new GenericObjectPoolConfig();config.setMaxTotal(maxActive);config.setMaxIdle(maxIdle);config.setMinIdle(minIdle);config.setMaxWaitMillis(maxWait);return config;}@Beanpublic RedisStandaloneConfiguration localRedisConfig() {RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();config.setHostName(host);config.setPassword(RedisPassword.of(password));config.setPort(port);config.setDatabase(database);return config;}}@Configurationpublic static class DefaultRedisConfig {@Value("${spring.redis.host:127.0.0.1}")private String host;@Value("${spring.redis.port:6379}")private Integer port;@Value("${spring.redis.password:}")private String password;@Value("${spring.redis.database:0}")private Integer database;@Value("${spring.redis.lettuce.pool.max-active:8}")private Integer maxActive;@Value("${spring.redis.lettuce.pool.max-idle:8}")private Integer maxIdle;@Value("${spring.redis.lettuce.pool.max-wait:-1}")private Long maxWait;@Value("${spring.redis.lettuce.pool.min-idle:0}")private Integer minIdle;private static final String PRIVATEKEY = "4334f34t2t2t54ytw4erg3y245g45wt4qf4";@Beanpublic GenericObjectPoolConfig defaultPoolConfig() {GenericObjectPoolConfig config = new GenericObjectPoolConfig();config.setMaxTotal(maxActive);config.setMaxIdle(maxIdle);config.setMinIdle(minIdle);config.setMaxWaitMillis(maxWait);return config;}@Beanpublic RedisStandaloneConfiguration defaultRedisConfig() {RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();config.setHostName(host);// config.setPassword(RedisPassword.of(password));config.setPassword(SM2Encryptor.decryptText(PRIVATEKEY, password)); // 此处密文需要解密config.setPort(port);config.setDatabase(database);return config;}}
}

测试类如下,简单的演示下两个template的读写

@SpringBootApplication
public class Application {public Application(RedisTemplate<String, String> localRedisTemplate, RedisTemplate<String, String>defaultRedisTemplate)throws InterruptedException {// 10s的有效时间localRedisTemplate.delete("key");localRedisTemplate.opsForValue().set("key", "value", 100, TimeUnit.MILLISECONDS);String ans = localRedisTemplate.opsForValue().get("key");System.out.println("value".equals(ans));TimeUnit.MILLISECONDS.sleep(200);ans = localRedisTemplate.opsForValue().get("key");System.out.println("value".equals(ans) + " >> false ans should be null! ans=[" + ans + "]");defaultRedisTemplate.opsForValue().set("key", "value", 100, TimeUnit.MILLISECONDS);ans = defaultRedisTemplate.opsForValue().get("key");System.out.println(ans);}public static void main(String[] args) {SpringApplication.run(Application.class, args);}
}

重点:

  • 注意 localRedisTemplate, defaultRedisTemplate 两个对象不相同(看debug窗口后面的@xxx)
  • 同样两个RedisTemplate的ConnectionFactory也是两个不同的实例(即分别对应前面配置类中的两个Factory)
  • 执行后输出的结果正如我们预期的redis操作
    • 塞值,马上取出没问题
    • 失效后,再查询,返回null
  • 最后输出异常日志,提示如下
Description:
Parameter 0 of method redisTemplate in org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration required a single bean, but 2 were found:- defaultLettuceConnectionFactory: defined by method 'defaultLettuceConnectionFactory' in class path resource [com/git/hui/boot/redis/config/RedisAutoConfig.class]- localLettuceConnectionFactory: defined by method 'localLettuceConnectionFactory' in class path resource [com/git/hui/boot/redis/config/RedisAutoConfig.class]Action:
Consider marking one of the beans as @Primary, updating the consumer to accept multiple beans, or using @Qualifier to identify the bean that should be consumed

上面表示说有多个ConnectionFactory存在,然后创建默认的RedisTemplate就不知道该选择哪一个了,有两种方法解决:
方法一:指定默认的ConnectionFactory
借助@Primary来指定默认的连接工厂,然后在使用工程的时候,通过@Qualifier注解来显示指定,我需要的工厂是哪个(主要是localRedisTemplate这个bean的定义,如果不加,则会根据defaultLettuceConnectionFactory这个实例来创建Redis连接了)

@Bean
@Primary
public LettuceConnectionFactory defaultLettuceConnectionFactory(RedisStandaloneConfiguration defaultRedisConfig,GenericObjectPoolConfig defaultPoolConfig) {// ...
}@Bean
public RedisTemplate<String, String> defaultRedisTemplate(@Qualifier("defaultLettuceConnectionFactory") LettuceConnectionFactory defaultLettuceConnectionFactory) {// ....
}@Bean
@ConditionalOnBean(name = "localRedisConfig")
public LettuceConnectionFactory localLettuceConnectionFactory(RedisStandaloneConfiguration localRedisConfig,GenericObjectPoolConfig localPoolConfig) {// ...
}@Bean
@ConditionalOnBean(name = "localLettuceConnectionFactory")
public RedisTemplate<String, String> localRedisTemplate(@Qualifier("localLettuceConnectionFactory") LettuceConnectionFactory localLettuceConnectionFactory) {// ...
}

方法二:忽略默认的自动配置类
既然提示的是org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration类加载bean冲突,那么就不加载这个配置即可

@SpringBootApplication
@EnableAutoConfiguration(exclude = {RedisAutoConfiguration.class, RedisReactiveAutoConfiguration.class})
public class Application {// ...
}

相关文章:

SpringBoot之RedisTemplate基本配置

公司要求redis配置密码使用密文&#xff0c;但是程序使用的是spring默认的redisTemplate&#xff0c;那么就需要修改配置实现密码加解密。 先搞个加密工具类&#xff1a; public class SM2Encryptor {// 加密&#xff0c;使用公钥public static String encryptText(String pub…...

SparseRCNN 模型,用于目标检测任务

SparseRCNN 模型,用于目标检测任务 import logging import math from typing import Listimport numpy as np import torch import torch.distributed as dist import torch.nn.functional as F from torch import nn #项目完整代码下载链接:https://download.csdn.net/downl…...

【AIGC】第一性原理下的ChatGPT提示词Prompt设计:系统信息与用户信息的深度融合

博客主页&#xff1a; [小ᶻZ࿆] 本文专栏: AIGC | ChatGPT 文章目录 &#x1f4af;前言&#x1f4af;第一性原理与ChatGPT提示词Prompt设计应用第一性原理于ChatGPT提示词Prompt设计系统信息和用户信息的融合实际应用结论 &#x1f4af;系统信息与用户信息的定义和重要性系…...

DeepSpeed性能调优与常见问题解决方案

1. 引言 什么是DeepSpeed&#xff1f; DeepSpeed是由微软开源的深度学习训练优化库&#xff0c;旨在帮助研究人员和工程师高效地训练大规模深度学习模型。基于PyTorch框架&#xff0c;DeepSpeed提供了一系列先进的技术&#xff0c;如ZeRO&#xff08;Zero Redundancy Optimiz…...

【GESP】C++一级练习BCQM3052,鸡兔同笼

GESP一级知识点&#xff1a;for循环和if的应用。 题目题解详见&#xff1a;https://www.coderli.com/gesp-1-bcqm3052/ 【GESP】C一级练习BCQM3052&#xff0c;鸡兔同笼 | OneCoderGESP一级知识点&#xff1a;for循环和if的应用。https://www.coderli.com/gesp-1-bcqm3052/ …...

Android面试之5个性能优化相关的深度面试题

本文首发于公众号“AntDream”&#xff0c;欢迎微信搜索“AntDream”&#xff0c;和我一起每天进步一点点 面试题目1&#xff1a;如何优化Android应用的启动速度&#xff1f; 解答&#xff1a; 优化Android应用的启动速度可以从以下几个方面入手&#xff1a; 1、 减少主线程工…...

R语言机器学习算法实战系列(六)K-邻近算法 (K-Nearest Neighbors)

禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者! 文章目录 介绍教程下载数据加载R包导入数据数据预处理数据描述数据切割调节参数构建模型预测测试数据评估模型模型准确性混淆矩阵模型评估指标ROC CurvePRC Curve保存模型总结系统信息介绍 K-邻…...

FPGA图像处理之构建3×3矩阵

免责声明&#xff1a;本文所提供的信息和内容仅供参考。作者对本文内容的准确性、完整性、及时性或适用性不作任何明示或暗示的保证。在任何情况下&#xff0c;作者不对因使用本文内容而导致的任何直接或间接损失承担责任&#xff0c;包括但不限于数据丢失、业务中断或其他经济…...

【Linux】进程间通信(匿名管道)

&#x1f308;个人主页&#xff1a;秦jh__https://blog.csdn.net/qinjh_?spm1010.2135.3001.5343&#x1f525; 系列专栏&#xff1a;https://blog.csdn.net/qinjh_/category_12625432.html 目录 进程间通信目的 进程间通信发展 进程间通信分类 管道 System V IPC POSI…...

memset()函数的实现

memset()函数的实现 _CRTIMP void* __cdecl memset (void*, int, size_t); memset()函数的实现 文章目录 memset()函数的实现memset()函数 memset()函数 _CRTIMP void* __cdecl memset (void*, int, size_t);void* memset(void* src, int val, size_t count) {char *char_src…...

STM32CUBEIDE FreeRTOS操作教程(七):queue队列

STM32CUBEIDE FreeRTOS操作教程&#xff08;七&#xff09;&#xff1a;queue队列 STM32CUBE开发环境集成了STM32 HAL库进行FreeRTOS配置和开发的组件&#xff0c;不需要用户自己进行FreeRTOS的移植。这里介绍最简化的用户操作类应用教程。以STM32F401RCT6开发板为例&#xff…...

类型转换与字符串操作:数据的灵活变形!

Java中的隐式与强制类型转换&#xff1a;让你轻松驾驭数据 在编程的世界中&#xff0c;数据的类型如同游戏中的角色&#xff0c;赋予它们不同的特性与能力。而在Java中&#xff0c;隐式类型转换与强制类型转换就像是两把利剑&#xff0c;帮助我们在这个复杂的世界中游刃有余。…...

动态规划18:188. 买卖股票的最佳时机 IV

动态规划解题步骤&#xff1a; 1.确定状态表示&#xff1a;dp[i]是什么 2.确定状态转移方程&#xff1a;dp[i]等于什么 3.初始化&#xff1a;确保状态转移方程不越界 4.确定填表顺序&#xff1a;根据状态转移方程即可确定填表顺序 5.确定返回值 题目链接&#xff1a;188.…...

YOLOv8改进 - 注意力篇 - 引入ShuffleAttention注意力机制

一、本文介绍 作为入门性篇章&#xff0c;这里介绍了ShuffleAttention注意力在YOLOv8中的使用。包含ShuffleAttention原理分析&#xff0c;ShuffleAttention的代码、ShuffleAttention的使用方法、以及添加以后的yaml文件及运行记录。 二、ShuffleAttention原理分析 ShuffleA…...

基于Multisim的8路彩灯循环控制电路设计与仿真

1)由八个彩灯LED的明暗构成各种彩灯图形; 2)彩灯依次显示的图形: 彩灯从左至右渐亮至全亮(8个CP) 彩灯从左至右渐灭至全灭(8个CP) 彩灯从右至左渐亮至全亮(8个CP) 彩灯从右至左渐灭至全灭(8个CP) 彩灯全亮(1个CP) 彩灯全灭(1个CP) 彩灯全亮(1个CP) 彩灯全灭(1个CP) 3)彩灯图形循…...

完整的模型训练套路 pytorch

**前置知识&#xff1a; 1、 &#xff08;1&#xff09;.train()&#xff1a;将模型设置为训练模式 &#xff08;2&#xff09;.eval()&#xff1a;将模型设置为评估模式 不写也可以&#xff08;只对特定网络模型有作用&#xff0c;如含有Dropout的&#xff09; 2、 with…...

2024年十大前沿图像分割模型汇总:工作机制、优点和缺点介绍

《博主简介》 小伙伴们好&#xff0c;我是阿旭。专注于人工智能、AIGC、python、计算机视觉相关分享研究。 ✌更多学习资源&#xff0c;可关注公-仲-hao:【阿旭算法与机器学习】&#xff0c;共同学习交流~ &#x1f44d;感谢小伙伴们点赞、关注&#xff01; 《------往期经典推…...

Notepad++将搜索内容所在行选中,并进行复制等操作

背景 Notepad在非常多的数据行内容中&#xff0c;按照指定内容检索&#xff0c;并定位到具体行&#xff0c;而后对内容行的数据进行复制、剪切、删除等处理动作。 操作说明 检索并标记所在行 弹出搜索框&#xff1a;按下 Ctrl F。 输入查找字符串&#xff1a;在搜索框中输入要…...

[Java EE] IP 协议 | NAT 机制 | 路由选择 | MAC 地址 | 域名解析服务

Author&#xff1a;MTingle major:人工智能 Build your hopes like a tower! 目录 一. 初识 IP 协议 IP 协议报头: 二. IP 协议如何管理地址 NAT机制 路由选择 三. 数据链路层(以太网): MAC地址 四. 域名解析系统 一. 初识 IP 协议 IP 协议工作在网络层,其目标是为了在复…...

赋能特大城市水务数据安全高速运算,深圳计算科学研究院YashanDB数据库系统斩获“鼎新杯”二等奖

第三届“鼎新杯”数字化转型应用优秀案例评选结果日前正式公布&#xff0c;深圳计算科学研究院联合深圳市环境水务集团有限公司申报的《深圳环境水务国产数据库YashanDB&#xff0c;赋能特大城市水务数据安全高速运转》案例&#xff0c;经过5个多月的评审&#xff0c;从4000申报…...

丹青识画GPU利用率优化指南:FP16量化+动态批处理实测

丹青识画GPU利用率优化指南&#xff1a;FP16量化动态批处理实测 1. 优化背景与价值 在实际部署丹青识画系统时&#xff0c;我们发现GPU资源利用率存在明显瓶颈。当用户同时上传多张图片进行识别时&#xff0c;GPU使用率波动很大&#xff0c;有时满载有时空闲&#xff0c;这种…...

告别‘夜盲症’:手把手教你用MFNet和热成像数据提升自动驾驶夜间语义分割精度

夜间自动驾驶的视觉革命&#xff1a;基于MFNet与热成像的语义分割实战指南 当一辆自动驾驶汽车在暴雨夜驶过无路灯的乡间公路时&#xff0c;传统摄像头捕捉到的画面几乎是一片模糊的灰色噪点。这正是2017年MFNet论文揭示的核心问题&#xff1a;单一可见光谱传感器在低照度环境下…...

Qwen3.5-9B镜像免配置教程:一行命令启动7860端口Web服务

Qwen3.5-9B镜像免配置教程&#xff1a;一行命令启动7860端口Web服务 1. 前言&#xff1a;为什么选择Qwen3.5-9B 如果你正在寻找一个功能强大又容易部署的多模态AI模型&#xff0c;Qwen3.5-9B绝对值得考虑。这个模型最大的特点就是"开箱即用"——不需要复杂的配置&a…...

从零到F:基于Vivado与EGo1的七段数码管译码器实战

1. 七段数码管译码器入门指南 第一次接触FPGA开发的朋友们&#xff0c;看到七段数码管可能会觉得既熟悉又陌生。我们日常生活中随处可见这种显示设备&#xff0c;比如电子钟、电梯楼层显示等。但要让它在开发板上正确显示字符&#xff0c;可不是简单接上线就能搞定的事。 七段数…...

警惕你身边做AI for Science的人

警惕你身边做AI for Science的人他们手持显卡账单&#xff0c;口称改变人类命运&#xff0c;用一张模型架构图解释一切&#xff0c;用一篇Nature子刊圆所有谎言。我先声明&#xff0c;我不是反对AI&#xff0c;也不是反对科学。我反对的&#xff0c;是那种特定的人。他们活在一…...

嵌入式轻量级协作式任务调度器设计与实现

1. 项目概述simple_task_scheduler是一个轻量级、无依赖的嵌入式任务调度器实现&#xff0c;专为资源受限的微控制器&#xff08;MCU&#xff09;环境设计。它不依赖操作系统内核、不使用动态内存分配、不引入中断上下文切换开销&#xff0c;仅通过纯 C 语言实现的协作式&#…...

GME-Qwen2-VL-2B企业级应用:基于Dify构建低代码多模态AI智能体

GME-Qwen2-VL-2B企业级应用&#xff1a;基于Dify构建低代码多模态AI智能体 最近在帮几个朋友的公司做AI项目落地&#xff0c;发现一个挺有意思的现象&#xff1a;很多业务团队对多模态AI&#xff08;就是能同时理解文字和图片的AI&#xff09;的需求很旺盛&#xff0c;但一提到…...

YOLOv8鹰眼目标检测避坑:统计看板数据不准怎么办?

YOLOv8鹰眼目标检测避坑&#xff1a;统计看板数据不准怎么办&#xff1f; 1. 问题现象与影响分析 当使用"鹰眼目标检测 - YOLOv8"镜像进行物体统计时&#xff0c;您可能会遇到以下典型问题&#xff1a; 数量统计偏差&#xff1a;实际画面中有10个人&#xff0c;但…...

Kali与编程・流量伪装・大白话版(超好懂)

​ 大家好&#xff0c;我是 Kali 与编程讲师老 K&#xff0c;B 站和网易云课堂讲师&#xff0c;致力于帮助小白轻松学会 Kali 与编程&#xff0c;接下来你将搞懂什么是《流量伪装》。 很多刚学渗透测试的小白&#xff0c;听到 “流量伪装” 就觉得很神秘&#xff0c;其实拆开来…...

思源宋体深度应用指南:从技术原理到实战优化

思源宋体深度应用指南&#xff1a;从技术原理到实战优化 【免费下载链接】source-han-serif-ttf Source Han Serif TTF 项目地址: https://gitcode.com/gh_mirrors/so/source-han-serif-ttf 在全球化数字内容创作浪潮中&#xff0c;中文字体的选择与应用直接关系到信息传…...