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

  

posted @   安逺  阅读(3300)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示