当前位置: 首页 > 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申报…...

RAYDATA链接PGSQL做图表

1.拖一个脚本进去 2.拖一个柱状图进去 3.双击脚本写代码 using System; using System.Collections; using System.Collections.Generic; using System.Linq; using Ventuz.Kernel; using Npgsql; using System.Threading; using System.Threading.Tasks;public class Script…...

UE5里的TObjectPtr TSharedPtr TWeakPtr有什么区别

在 Unreal Engine&#xff08;UE&#xff09;编程中&#xff0c;TObjectPtr、TSharedPtr 和 TWeakPtr 都是 指针类型&#xff0c;但它们在生命周期管理和使用场景上有不同的特点。让我们详细分析这些指针的区别和用途。 TObjectPtr TObjectPtr 是 UE5 中引入的新智能指针类型…...

前端--深入理解HTTP协议

HTTP 协议简介 HTTP&#xff08;HyperText Transfer Protocol&#xff0c;超文本传输协议&#xff09;是一个应用层协议&#xff0c;用于在客户端&#xff08;通常是浏览器&#xff09;和服务器之间传输超文本数据&#xff08;如 HTML、CSS、JavaScript 等&#xff09;。它是万…...

线性代数 向量

一、定义 几何定义&#xff1a;向量是一个有方向和大小的量&#xff0c;通常用箭头表示。向量的起点称为原点&#xff0c;终点称为向量的端点。 代数定义&#xff1a;向量是一个有序的数组&#xff0c;通常表示为列向量或行向量。 行向量就是 1*n的形式&#xff08;行展开&…...

go中阶乘实现时递归及迭代方式的比较

package mainimport ("fmt""time""math/big" )// 使用递归和 big.Int 计算阶乘 func FactorialRecursive(n *big.Int) *big.Int {if n.Cmp(big.NewInt(0)) 0 {return big.NewInt(1)}return new(big.Int).Mul(n, FactorialRecursive(new(big.Int…...

Jupyter notebook中更改字体大小

文章目录 方法一&#xff1a;局部修改方法二&#xff1a;全局修改 Jupyter notebook提供了一个非常方便的跨平台交互代码编译环境&#xff0c;但是单元格的内的代码字体往往显示较小&#xff0c;不利于观看。本人查了很多方法来调整字体&#xff0c;后来发现既不需要更改jupyte…...

关于Ubuntu服务器的时间同步设置以及Linux什么时候开始使用swap虚拟内存

一、关于Ubuntu服务器的时间同步设置 首先我们检查一下服务器的时区设置和当前时间值&#xff0c;获取/etc/timezone 配置以及使用date命令查看当前时间。 rootiZ2ze7n2ynw18p6bs92fziZ:~# cat /etc/timezone Asia/Shanghai rootiZ2ze7n2ynw18p6bs92fziZ:~# date Wed Dec 21 …...

Java Stream API 详解

Java Stream API 详解 1. 什么是 Stream API&#xff1f; Stream API 是 Java 8 引入的一种用于处理集合&#xff08;如数组、列表&#xff09;的强大工具。它提供了一种声明性方式处理数据&#xff0c;可以简化代码并提高可读性。Stream 不是数据结构&#xff0c;它只是一种…...

一文了解大模型中的SDK和API

大白话聊SDK和API-知乎 1.智谱AI的SDK和API 以智谱AI为例&#xff0c;智谱AI的SDK是名为zhipuai的Python包&#xff0c;其中包含了用于访问API的接口&#xff08;如api-key&#xff09;。在这个框架中&#xff0c;API是SDK的一部分&#xff0c;用于实现与智谱AI服务的交互。 …...

element plus的el-select分页

摘要&#xff1a; el-select的数据比较多的时候&#xff0c;必须要分页&#xff0c;处理方案有全部数据回来&#xff0c;或者添加搜索功能&#xff0c;但是就有个问题就是编辑的时候回显问题&#xff0c;必须要保证select的数据有对应的id与name匹配回显&#xff01; <el-fo…...