最近项目中遇到需要连接两个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. mysql 5.6 datetime default now()

    CREATE TABLE `test` (   id int,   `gmt_create` datetime  DEFAULT NOW() not NULL )ENGINE=InnoDB; mysq ...

  2. [BZOJ] 聚会

    问题描述 Y 岛风景美丽宜人,气候温和,物产丰富.Y 岛上有 N 个城市,有 N-1 条城市间的道路连接着它们.每一条道路都连接某两个城市.幸运的是,小可可通过这些道路可以走遍 Y岛的所有城市. 神奇 ...

  3. javascrip的数组扁平化

    扁平化 数组的扁平化,就是将一个嵌套多层的数组 array (嵌套可以是任何层数)转换为只有一层的数组. 举个例子,假设有个名为 flatten 的函数可以做到数组扁平化,效果就会如下: var ar ...

  4. 预览下载的pdf的——pdf.js

    1.需要到官网下载源码:https://mozilla.github.io/pdf.js/ 2. function(){ let url='./demo1.pdf'; window.location. ...

  5. Java 迭代器删除元素ConcurrentModificationException异常。

    Java是不支持容器类在使用迭代器迭代过程中,使用如 list.remove(obj)方法删除元素.否则会抛出ava.util.ConcurrentModificationException异常.应该 ...

  6. iOS设计模式之桥接模式

    一,什么是桥接模式 定义 抽象出层次结构.上层抽象接口的职能,实现上层抽象接口的职能,层级间的通信协议(可以抽象为接口).桥接模式的目的,就是把抽象层次结构从具体的实现中分离出来,使其能够独立变更.抽 ...

  7. TreeView拖动并存入数据库(可判断拖动)

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...

  8. 20180820-Java 抽象类

    Java 抽象类 在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类. 抽象类除了不 ...

  9. Oracle数据库字符集问题

    Oracle数据库的字符集问题,也涉及作为服务器操作系统的CentOS或者Windows的字符集与Oracle字符集之间的关联关系Oracle的字符集,这个问题的提出是因为两个原因:一是遇到一个DMP ...

  10. 用 margin 还是用 padding ?

    边界(margin):元素周围生成额外的空白区."空白区"通常是指其他元素不能出现且父元素背景可见的区域. 补白(padding):补白位于元素框的边界与内容区之间.很自然,用于影 ...