最近项目中遇到需要连接两个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. canvas一个简单粗暴的中奖转盘

    最近在学canvas做动画,于是就写个转盘练下手.上个简陋的成果图(中间那个是转的指针,外面的圈是图片,懒得写了哈哈哈) 代码很简单,都注释了,直接上代码吧,嘤嘤嘤 html <body> ...

  2. django之创建项目

    1.创建虚拟环境 mkvirtualenv django_study -p python3 创建成功后:(django_study) python@ubuntu:~$ 2.安装django-指定版本1 ...

  3. windows下zookeeper集群安装

    windows下zookeeper单机版安装,见:https://www.cnblogs.com/lbky/p/9867899.html 一:zookeeper节点为什么是奇数个? 单机模式的zk进程 ...

  4. LocalDateTime用法(jdk1.8 )

    前言 最近看别人项目源码,发现Java8新的日期时间API很方便强大,所以转载该入门介绍博客,记录一下. 使用新时间日期API的必要性 在java8以前,或许: 当你在做有关时间日期的操作时,你会想到 ...

  5. 对getBoundingClientRect属性的研究

    1.getBoundingClientRect用于获取某个元素相对于视窗的位置集合.集合中有top, right, bottom, left等属性. .top:元素上边到视窗上边的距离; right: ...

  6. 日志管理工具logrotate

    工作所需,需要管理脚本的打印日志,百度一圈,发现了logrotate这款工具,经测试确实挺好的! 话不多说,直接上重点,以便于以后需要时查看 命令: whereis logrotate 可以看到log ...

  7. 一探究竟:善用 MaxCompute Studio 分析 SQL 作业

    头疼的问题 MaxCompute 用户一个常见的问题是:同一个周期任务,为什么最近几天比之前慢了很多?或者为什么之前都能按时产出的作业最近经常破线? 通常来说,引起作业执行变慢的原因有:quota 组 ...

  8. PHP中什么是数组

    PHP 中的数组实际上是一个有序映射.映射是一种把 values 关联到 keys 的类型. 此类型在很多方面做了优化,因此可以把它当成真正的数组,或列表(向量),散列表(是映射的一种实现),字典,集 ...

  9. 【説明する】STL

    作为C++标准不可缺少的一部分,STL应该是渗透在C++程序的角角落落里的. STL不是实验室里的宠儿,也不是程序员桌上的摆设,她的激动人心并非昙花一现. 所以今天要整理的东西就是STL!(orz 杨 ...

  10. 【HDOJ6662】Acesrc and Travel(树形DP,换根)

    题意:有一棵n个点的树,每个点上有两个值a[i],b[i] A和B在树上行动,A到达i能得到a[i]的偷税值,B能得到b[i],每次行动只能选择相邻的点作为目标 两个人都想最大化自己的偷税值和对方的差 ...