Java SpringBoot配置Redis多数据源
写了一个功能实时性要求比较高,读写操作也很频繁,决定逻辑层使用Redis支持,当流程结束后再做数据持久化。因为该功能有高并发需求且数据比较独立,配置了一个独立的Redis使用
pom.xml 文件引入Redis依赖:spring-boot-starter-data-redis 、线程池:commons-pool2 :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | <dependencies> ... <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> <version> 2.1 . 3 .RELEASE</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-pool2</artifactId> <version> 2.9 . 0 </version> </dependency> ... </dependencies> |
在 配置文件 application.yml 添加Redis配置:
1: 配置一个端口为6379的默认Redis;
2: 配置一个端口为6380的 UserRedis;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | spring: redis: host: localhost port: 6379 timeout: 3000 database: 0 <br> # 第二个redis配置 redis-user: # Host host: localhost # 密码 password: # 端口 port: 6380 # 超时时间 timeout: 3000 # 数据库 database: 0 # 连接池最大活跃连接数 max-active: 100 # 连接池最大建立连接等待时间, 单位为ms, 如果超过此时间将抛出异常 max-wait: 3000 # 连接池最大空闲连接数, 超过空闲数将被标记为不可用,然后被释放 max-idle: 20 # 连接池里始终应该保持的最小连接数 min-idle: 0 |
这里将端口6380的Redis作为User逻辑独立使用,创建一个读取UserRedis配置类:UserRedisProperties.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | package com.demo.redisdemo.config.redis; import lombok.Data; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; /** * @author AnYuan */ @Data @Component // 配置前缀 @ConfigurationProperties ( prefix = "spring.redis-user" ) public class UserRedisProperties { /** * 配置里面的中划线: '-' 转为驼峰写法即可读取配置 */ private String host; private String password; private int port; private int timeout; private int database; private int maxWait; private int maxActive; private int maxIdle; private int minIdle; } |
创建一个初始化的配置类:RedisConfigure.java,声明一个 @Bean ,设置好对应的参数,创建第二个RedisTemplate。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 | package com.demo.redisdemo.config.redis; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; import org.apache.logging.log4j.util.Strings; import org.springframework.beans.factory.annotation.Autowired; 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.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.RedisPassword; import org.springframework.data.redis.connection.RedisStandaloneConfiguration; 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.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import java.time.Duration; /** * Redis 初始化配置 * @author AnYuan */ @Configuration @EnableCaching public class RedisConfigure extends CachingConfigurerSupport { @Autowired private UserRedisProperties userRedisProperties; /** * @Bean: * 1: 这里声明该方法返回的是受Spring容器管理的Bean * 2: 方法名与返回类名一致 redisTemplateUser */ @Bean public <T> RedisTemplate<String, T> redisTemplateUser() { // 基本配置 RedisStandaloneConfiguration configuration = new RedisStandaloneConfiguration(); configuration.setHostName(userRedisProperties.getHost()); configuration.setPort(userRedisProperties.getPort()); configuration.setDatabase(userRedisProperties.getDatabase()); if (Strings.isNotBlank(userRedisProperties.getPassword())) { configuration.setPassword(RedisPassword.of(userRedisProperties.getPassword())); } // 连接池配置 GenericObjectPoolConfig<Object> genericObjectPoolConfig = new GenericObjectPoolConfig<>(); genericObjectPoolConfig.setMaxTotal(userRedisProperties.getMaxActive()); genericObjectPoolConfig.setMaxWaitMillis(userRedisProperties.getMaxWait()); genericObjectPoolConfig.setMaxIdle(userRedisProperties.getMaxIdle()); genericObjectPoolConfig.setMinIdle(userRedisProperties.getMinIdle()); // lettuce pool LettucePoolingClientConfiguration.LettucePoolingClientConfigurationBuilder builder = LettucePoolingClientConfiguration.builder(); builder.poolConfig(genericObjectPoolConfig); builder.commandTimeout(Duration.ofSeconds(userRedisProperties.getTimeout())); LettuceConnectionFactory lettuceConnectionFactory = new LettuceConnectionFactory(configuration, builder.build()); lettuceConnectionFactory.afterPropertiesSet(); return createRedisTemplate(lettuceConnectionFactory); } private <T> RedisTemplate<String, T> createRedisTemplate(RedisConnectionFactory redisConnectionFactory) { RedisTemplate<String, T> stringObjectRedisTemplate = new RedisTemplate<>(); stringObjectRedisTemplate.setConnectionFactory(redisConnectionFactory); RedisSerializer<String> redisSerializer = new StringRedisSerializer(); // key序列化 stringObjectRedisTemplate.setKeySerializer(redisSerializer); // value序列化 stringObjectRedisTemplate.setValueSerializer(redisSerializer); // value hashMap序列化 stringObjectRedisTemplate.setHashValueSerializer(redisSerializer); // key haspMap序列化 stringObjectRedisTemplate.setHashKeySerializer(redisSerializer); return stringObjectRedisTemplate; } } |
启动SpringBoot应用,Spring的容器里面就管理着一个name为redisTemplateUser的Bean,通过这个Bean可以使用第二个数据源的Redis。
单元测试创建一个测试类:RedisTest.java :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | package com.demo.redisdemo.redis; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import java.util.concurrent.TimeUnit; @SpringBootTest public class RedisTest { /** * 当一个接口有多个实现类的时候 * 将 @Qualifier 注解使用的 Spring Bean 名称一起进行装配 * Spring 框架就能从多个相同类型并满足装配要求的 Bean 中找到对应的Bean * * 这里绑定初始化里面注入的Bean:redisTemplateUser */ /** * 第二个数据源的配置并指定String数据类型 UserRedis */ @Autowired @Qualifier ( "redisTemplateUser" ) private RedisTemplate<String, String> redisTemplateUser; /** * 默认数据源配置并指定String数据类型的Redis */ @Autowired private RedisTemplate<String, String> redisTemplate; /** * 默认数据源配置的String数据类型的Redis */ @Autowired private StringRedisTemplate stringRedisTemplate; @Test public void redisTest() { System.out.println( "----------Start----------" ); // 端口6380的Redis redisTemplateUser.opsForValue().set( "redisTemplateUser" , "success" , 1 , TimeUnit.DAYS); // 端口6379默认Redis redisTemplate.opsForValue().set( "redisTemplate" , "success" , 1 , TimeUnit.DAYS); // 端口6379并指定String数据类型的默认Redis stringRedisTemplate.opsForValue().set( "stringRedisTemplate" , "success" , 1 , TimeUnit.DAYS); System.out.println( "----------End----------" ); } } |
最后开启两个Redis,当前无数据:
运行测试用例后,再查看Redis的缓存情况:
引入扩展包,配置多数据源,读取数据源,初始化Bean,最后使用@Qualifier注解并指定前面Bean注入的名字就可以操作了
本篇代码Github:https://github.com/Journeyerr/cnblogs/tree/master/redisDemo
Redis扩展包:https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis
线程池扩展包:https://mvnrepository.com/artifact/org.apache.commons/commons-pool2
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix