最近项目中遇到需要连接两个redis实例的情况,于是就在spring boot原先的基础上修改了一点。

首先,添加所需的依赖

        <dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
<version>2.7.0</version>
</dependency> <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

1. 定义配置文件的bean,继承自RedisProperties

  • 下面是配置文件的内容
redis:
config:
multiple:
- name: develop
database: 0
lettuce:
pool:
max-idle: 10
max-active: 1000
max-wait: 1000ms
min-idle: 5
timeout: 100000ms
cluster:
nodes: 192.168.2.86:6380,192.168.2.87:6380,192.168.2.88:6380
- name: test
database: 0
lettuce:
pool:
max-idle: 10
max-active: 1000
max-wait: 1000ms
min-idle: 5
timeout: 100000ms
cluster:
nodes: 192.168.2.86:6379,192.168.2.87:6379,192.168.2.88:6379
  • 配置文件对应的实体
@Data
public class MultipleRedisProperties extends RedisProperties { /**
* redis的自定义名称
*/
private String name; }

2. 获取配置文件属性的值

@Getter
@Setter
@ConfigurationProperties(prefix = "redis.config")
public class RedisConfigPropertySupport { List<MultipleRedisProperties> multiple = new ArrayList<>(); }

3.加载到spring 容器中

@Getter
@Setter
@Configuration
@EnableConfigurationProperties(RedisConfigPropertySupport.class)
public class RedisPropertiesAutoConfig { private RedisConfigPropertySupport redisProperties; public RedisPropertiesAutoConfig(RedisConfigPropertySupport redisProperties) {
this.redisProperties = redisProperties;
}
}
  • 创建redis部署模式的枚举值
public enum RedisModeEnum {

    /**
* 单机
*/
STAND_ALONE, /**
* 哨兵
*/
SENTINEL, /**
* 集群
*/
CLUSTER }

4. 使用spring boot的创建连接工厂进行配置redis的连接工厂类

public abstract class AbstractRedisConnectionFactoryConfig implements BeanFactoryAware, InitializingBean {

    @Autowired
private RedisPropertiesAutoConfig redisProperties; private BeanFactory beanFactory; private static final String DEFAULT = "default"; @Override
public void afterPropertiesSet() {
ConfigurableListableBeanFactory listableBeanFactory = (ConfigurableListableBeanFactory) this.getBeanFactory();
if (getRedisProperties().getRedisProperties() == null || CollectionUtils.isEmpty(getRedisProperties().getRedisProperties().getMultiple())) {
RedisConnectionFactory defaultConnectionFactory = buildRedisConnectionFactory(null);
listableBeanFactory.registerSingleton(DEFAULT + "_redisConnectionFactory", defaultConnectionFactory);
}
getRedisProperties().getRedisProperties().getMultiple().forEach(redisProperty -> {
RedisConnectionFactory redisConnectionFactory = buildRedisConnectionFactory(redisProperty);
listableBeanFactory.registerSingleton(redisProperty.getName().trim() + "_redisConnectionFactory", redisConnectionFactory);
});
} /**
* 创建{@link RedisConnectionFactory},由子类实现
*
* @param redisProperties
* @return
*/
protected abstract RedisConnectionFactory buildRedisConnectionFactory(RedisProperties redisProperties); /**
* 根据redisProperty判断redis部署模式
*
* @param redisProperty redisProperty
* @return {@link RedisModeEnum}
*/
protected abstract RedisModeEnum getRedisMode(RedisProperties redisProperty); static class RedisConnectionPoolBuilderFactory { public LettuceClientConfiguration.LettuceClientConfigurationBuilder createBuilder(RedisProperties.Pool properties) {
return LettucePoolingClientConfiguration.builder().poolConfig(getPoolConfig(properties));
} private GenericObjectPoolConfig<?> getPoolConfig(RedisProperties.Pool properties) {
GenericObjectPoolConfig<?> config = new GenericObjectPoolConfig<>();
config.setMaxTotal(properties.getMaxActive());
config.setMaxIdle(properties.getMaxIdle());
config.setMinIdle(properties.getMinIdle());
if (properties.getTimeBetweenEvictionRuns() != null) {
config.setTimeBetweenEvictionRunsMillis(properties.getTimeBetweenEvictionRuns().toMillis());
}
if (properties.getMaxWait() != null) {
config.setMaxWaitMillis(properties.getMaxWait().toMillis());
}
return config;
}
} @Override
public void setBeanFactory(@Nullable BeanFactory beanFactory) throws BeansException {
this.beanFactory = beanFactory;
} public BeanFactory getBeanFactory() {
return beanFactory;
} public RedisPropertiesAutoConfig getRedisProperties() {
return redisProperties;
}
}
  • 工厂实现类
@Configuration
public class LettuceRedisConnectionFactoryConfig extends AbstractRedisConnectionFactoryConfig { @Override
protected RedisConnectionFactory buildRedisConnectionFactory(RedisProperties redisProperty) {
if (redisProperty == null) {
//创建默认的redis连接工厂
LettuceConnectionFactory defaultConnectionFactory = createDefaultConnectionFactory(); defaultConnectionFactory.afterPropertiesSet();
return defaultConnectionFactory;
}
LettuceClientConfiguration clientConfig = buildLettuceClientConfiguration(DefaultClientResources.create(),
redisProperty.getLettuce().getPool(), redisProperty);
//创建lettuce连接工厂
LettuceConnectionFactory redisConnectionFactory;
if (getRedisMode(redisProperty) == RedisModeEnum.CLUSTER) {
redisConnectionFactory = new LettuceConnectionFactory(new RedisClusterConfiguration
(redisProperty.getCluster().getNodes()), clientConfig);
} else if (getRedisMode(redisProperty) == RedisModeEnum.SENTINEL) {
redisConnectionFactory = new LettuceConnectionFactory(new RedisSentinelConfiguration
(redisProperty.getSentinel().getMaster(), new HashSet<>(redisProperty.getSentinel().getNodes())), clientConfig);
} else {
redisConnectionFactory = new LettuceConnectionFactory(new RedisStandaloneConfiguration
(redisProperty.getHost(), redisProperty.getPort()), clientConfig);
} redisConnectionFactory.afterPropertiesSet();
return redisConnectionFactory;
} @Override
protected RedisModeEnum getRedisMode(RedisProperties redisProperty) {
if (redisProperty.getCluster() != null) {
Assert.notNull(redisProperty.getCluster().getNodes(), "集群节点不能为空");
return RedisModeEnum.CLUSTER;
} else if (redisProperty.getSentinel() != null) {
Assert.hasText(redisProperty.getSentinel().getMaster(), "哨兵的主节点不能为空");
Assert.notNull(redisProperty.getSentinel().getNodes(), "哨兵的从节点不能为空");
return RedisModeEnum.SENTINEL;
}
return RedisModeEnum.STAND_ALONE;
} private LettuceClientConfiguration buildLettuceClientConfiguration(ClientResources clientResources, RedisProperties.Pool pool, RedisProperties redisProperties) {
LettuceClientConfiguration.LettuceClientConfigurationBuilder builder = createBuilder(pool);
applyProperties(builder, redisProperties);
builder.clientResources(clientResources);
return builder.build();
} private LettuceClientConfiguration.LettuceClientConfigurationBuilder applyProperties(
LettuceClientConfiguration.LettuceClientConfigurationBuilder builder, RedisProperties redisProperties) {
if (redisProperties.isSsl()) {
builder.useSsl();
}
if (redisProperties.getTimeout() != null) {
builder.commandTimeout(redisProperties.getTimeout());
}
if (redisProperties.getLettuce() != null) {
RedisProperties.Lettuce lettuce = redisProperties.getLettuce();
if (lettuce.getShutdownTimeout() != null && !lettuce.getShutdownTimeout().isZero()) {
builder.shutdownTimeout(redisProperties.getLettuce().getShutdownTimeout());
}
}
return builder;
} private LettuceClientConfiguration.LettuceClientConfigurationBuilder createBuilder(RedisProperties.Pool pool) {
if (pool == null) {
return LettuceClientConfiguration.builder();
}
return new RedisConnectionPoolBuilderFactory().createBuilder(pool);
} private LettuceConnectionFactory createDefaultConnectionFactory() {
return new LettuceConnectionFactory(new RedisStandaloneConfiguration());
}
}

5.redisTemplate的配置

public abstract class AbstractRedisConfiguration implements ApplicationContextAware {

    private ApplicationContext applicationContext;

    protected RedisTemplate<String, Object> buildRedisTemplate(String name) {
return buildRedisTemplate(name, new GenericJackson2JsonRedisSerializer(), false);
} protected RedisTemplate<String, Object> buildRedisTemplate(String name, Boolean enableTransaction) {
return buildRedisTemplate(name, new GenericJackson2JsonRedisSerializer(), enableTransaction);
} protected RedisTemplate<String, Object> buildRedisTemplate(String name, RedisSerializer redisSerializer,
Boolean enableTransaction) {
if (StringUtils.isBlank(name)) {
throw new IllegalArgumentException("redis properties name field must not null");
}
RedisConnectionFactory redisConnectionFactory = getRedisConnectionFactory(name);
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(redisSerializer);
redisTemplate.setHashValueSerializer(redisSerializer);
redisTemplate.setEnableTransactionSupport(enableTransaction);
return redisTemplate;
} private RedisConnectionFactory getRedisConnectionFactory(String name) {
return (RedisConnectionFactory) applicationContext.getBean(name.trim() + "_redisConnectionFactory");
} @Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
} }
  • 配置redisTemplate
@Configuration
@DependsOn("lettuceRedisConnectionFactoryConfig")
public class RedisConfiguration extends AbstractRedisConfiguration { @Bean("developRedisTemplate")
public RedisTemplate<String, Object> getDevelopRedisTemplate() {
return buildRedisTemplate("develop");
} @Bean("testRedisTemplate")
public RedisTemplate<String, Object> getTestRedisTemplate() {
return buildRedisTemplate("test");
}
}
  • 下面利用spring boot的ApplicationRunner接口测试一下,用redis客户端查看发现结果已经存入进去了。
     @Autowired
@Qualifier("developRedisTemplate")
private RedisTemplate developRedisTemplate; @Autowired
@Qualifier("testRedisTemplate")
private RedisTemplate testRedisTemplate; @Override
public void run(ApplicationArguments args) throws Exception {
developRedisTemplate.opsForValue().set("develop_RedisMultiple", "test", 120, TimeUnit.SECONDS);
testRedisTemplate.opsForValue().set("test_RedisMultiple", "test", 120, TimeUnit.SECONDS);
}

spring boot整合redis多实例的更多相关文章

  1. Spring Boot 整合 Redis 和 JavaMailSender 实现邮箱注册功能

    Spring Boot 整合 Redis 和 JavaMailSender 实现邮箱注册功能 开篇 现在的网站基本都有邮件注册功能,毕竟可以通过邮件定期的给用户发送一些 垃圾邮件 精选推荐

  2. SpringBoot入门系列(七)Spring Boot整合Redis缓存

    前面介绍了Spring Boot 中的整合Mybatis并实现增删改查,.不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/category/ ...

  3. (转)spring boot整合redis

    一篇写的更清晰的文章,包括redis序列化:http://makaidong.com/ncjava/330749_5285125.html 1.项目目录结构 2.引入所需jar包 <!-- Sp ...

  4. Spring Boot2 系列教程(二十六)Spring Boot 整合 Redis

    在 Redis 出现之前,我们的缓存框架各种各样,有了 Redis ,缓存方案基本上都统一了,关于 Redis,松哥之前有一个系列教程,尚不了解 Redis 的小伙伴可以参考这个教程: Redis 教 ...

  5. Spring Boot 整合 Redis 实现缓存操作

    摘要: 原创出处 www.bysocket.com 「泥瓦匠BYSocket 」欢迎转载,保留摘要,谢谢!   『 产品没有价值,开发团队再优秀也无济于事 – <启示录> 』   本文提纲 ...

  6. spring boot整合redis,以及设置缓存过期时间

    spring-boot 整合 redis 注:redis服务器要先开启 pom文件: <dependency> <groupId>org.springframework.boo ...

  7. spring boot 2.x 系列 —— spring boot 整合 redis

    文章目录 一.说明 1.1 项目结构 1.2 项目主要依赖 二.整合 Redis 2.1 在application.yml 中配置redis数据源 2.2 封装redis基本操作 2.3 redisT ...

  8. Spring Boot2 系列教程(二十九)Spring Boot 整合 Redis

    经过 Spring Boot 的整合封装与自动化配置,在 Spring Boot 中整合Redis 已经变得非常容易了,开发者只需要引入 Spring Data Redis 依赖,然后简单配下 red ...

  9. Spring Boot 整合Redis 实现缓存

      本文提纲 一.缓存的应用场景 二.更新缓存的策略 三.运行 springboot-mybatis-redis 工程案例 四.springboot-mybatis-redis 工程代码配置详解   ...

随机推荐

  1. Ubuntu环境下SSH服务安装、SSH远程登录以及SSH数据传输

    https://www.cnblogs.com/asyang1/p/9467646.html SSH 为 Secure Shell 的缩写,为建立在应用层基础上的安全通信协议. 一.检查SSH服务是否 ...

  2. $[WC2018]$通道(虚树,边分练习)

    \([WC2018]\)通道(虚树,边分练习) 感受码题的快感 这段时间真的是忙忙忙忙忙,省选之前还是露个脸,免得以后没机会了. 但是我感觉我的博客真的没啥人看,虽然我挺想要有人看的,但是自己真的没啥 ...

  3. 【leetcode】447. Number of Boomerangs

    题目如下: 解题思路:我首先用来时间复杂度是O(n^3)的解法,会判定为超时:后来尝试O(n^2)的解法,可以被AC.对于任意一个点,我们都可以计算出它与其余点的距离,使用一个字典保存每个距离的点的数 ...

  4. linux运维、架构之路-正则表达式

    一.通配符的含义 符号 参数说明 其他说明 | 管道 把前一个命令结果通过管道传递给后面一个命令 ; 命令的分隔符 ll /oldboy/;cat oldboy.tx . 表示当前目录 * 匹配文本或 ...

  5. Dubbo 在跨语言和协议穿透性方向的探索:支持 HTTP/2 gRPC

    Dubbo 在跨语言和协议穿透性方向上的探索:支持 HTTP/2 gRPC 和 Protobuf 本文整理自刘军在 Dubbo 成都 meetup 上分享的<Dubbo 在多语言和协议穿透性方向 ...

  6. 862C - Mahmoud and Ehab and the xor(构造)

    原题链接:http://codeforces.com/contest/862/problem/C 题意:给出n,x,求n个不同的数,使这些数的异或和为x 思路:(官方题解)只有n==2&&am ...

  7. 2017ICPC沈阳网络赛 HDU 6205 -- card card card(最大子段和)

    card card card Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)To ...

  8. Android签名机制之---签名验证过程详解

    一.前言 今天是元旦,也是Single Dog的嚎叫之日,只能写博客来祛除寂寞了,今天我们继续来看一下Android中的签名机制的姊妹篇:Android中是如何验证一个Apk的签名.在前一篇文章中我们 ...

  9. <自动化测试>之<自动获取手机短信验证码>

    第一次写博,最近解决了做自动化测试短信验证码自动获取填入的方法减少了脚本的人工干预,并非拦截短信,所以不存在安全警报提醒,拿出来分享给大家,有感兴趣的大家可以加Q1856100 目前在职测试开发,,写 ...

  10. ORACLE 收缩表空间的数据文件

    http://blog.itpub.net/29345367/viewspace-1816427/ 方法一: 在实际的应用中经常会遇到TRUNCATE或者DELETE表中的数据后发现表空间并没有将空间 ...