最近项目中遇到需要连接两个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. 【转】 linux硬链接与软链接

    转自:http://www.cnblogs.com/yfanqiu/archive/2012/06/11/2545556.html Linux 系统中有软链接和硬链接两种特殊的“文件”. 软链接可以看 ...

  2. 2014-03-01 春季PAT 1073-1076解题报告

    今天下午的PAT考试状态不理想,回来怒刷了一遍,解题报告如下: 1073. Scientific Notation (20) 基本模拟题,将一长串的科学计数转换为普通的数字表示方式.思路是是数组存储输 ...

  3. git 日常 常用命令

    初始化git git init 第一次拉代码: 方式1:git clone git clone https://git.oschina.net/*****.git (https远程仓库地址) 方式2: ...

  4. gitignore 忽略文件

    *.project*.prefs*.classpath*.gitignore#ignore thumbnails created by windowsThumbs.db#Ignore files bu ...

  5. 快速开发框架下载地址(github)

    eladmin:https://github.com/elunez/eladmin bootDo:https://www.oschina.net/p/bootdo

  6. python 日期生成和时间格式化

    记录下日期时间的转换和生成:1.这个是使用datetime 函数生成往后几天的时间,比如当前日期是2019-07-01 那么控制days=1然后再和当前的时间相加,就能得到明天的日期def time_ ...

  7. 利用已控的标边界一台机器的 beacon对目标内网进行各种存活探测

    本节的知识摘要: 基于常规 tcp / udp 端口扫描的内网存活探测 基于 icmp 的内网存活探测 基于 arp 的内网存活探测 加载外部脚本进行的各种存活探测 基础环境说明:: WebServe ...

  8. INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES

    [转] https://www.mobibrw.com/2016/3949 adb install 一个apk错误: INSTALL_FAILED_ALREADY_EXISTS 应用已存在,使用 ad ...

  9. BeautifulSoup笔记

    ## find_all的使用: 1. 在提取标签的时候,第一个参数是标签的名字.然后如果在提取标签的时候想要使用标签属性进行过滤,那么可以在这个方法中通过关键字参数的形式,将属性的名字以及对应的值传进 ...

  10. git 几个commit点合并成一个commit点

    在用git做版本控制器的时候,经常会遇到以下情况: 1.在做1个功能的时候,你自己觉得代码没问题了,就本地commit,然后提交代码,在gitlab上发起和并请求,老大看完之后,觉得你还有修改的地方, ...