Spring boot 使用多个RedisTemplate

问题描述

想在一个JAVA Class 向同一个Redis实例的不同 dbindex 写入数据,非常类似于StackOverflowe上的[How can select dbIndex when I use RedisTemplate in Spring-Data-Redis?。在这篇文章中描述了如何使用Spring boot访问Redis,在创建JedisConnectionFactory的时候指定dbindex:

JedisConnectionFactory factory = new JedisConnectionFactory();
...
factory.setDatabase(databaseId);//set dbindex

因此,大概思路是配置2个RedisTemplate,其中一个RedisTemplate负责访问dbindex=1的数据库;另一个RedisTemplate负责访问dbindex=3的数据库。

根据这篇文章,因此通过 @Bean(name=) 生成多个RedisTemplate。但是由于生成RedisTemplate需要传入JedisConnectionFactory实例,而我们是在JedisConnectionFactory中指定了访问Redis的哪个数据库(dbindex)。因此,就在创建JedisConnectionFactory实例的时候,使用 @Scope(scopeName = "prototype") 注解,这样的话Jedis连接工厂就不再是单例模式了。因此,就有两个JedisConnectionFactory实例,每个实例通过jedisConnectionFactory.setDatabase()设置不同的dbindex。这种方式可能非常愚蠢,会引起严重的性能问题。

下面,来看看具体是怎么配置的:

    @Scope(scopeName = "prototype")
    public JedisConnectionFactory jedisConnectionFactory() {

    JedisPoolConfig config = getRedisConfig();
    JedisConnectionFactory factory = new JedisConnectionFactory(config);
    factory.setUsePool(true);
    factory.setHostName(host);
    factory.setPort(port);
    return factory;
    }

每调用一次jedisConnectionFactory() 返回一个新的JedisConnectionFactory实例。

然后定义2个RedisTemplate Bean,jedisConnectionFactory.setDatabase() 方法分别设置不同的dbindex

 import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import redis.clients.jedis.JedisPoolConfig;
import java.util.Map;

/**
 * Created by Administrator on 2018/4/9.
 */

@Configuration
public class LoginMacRedisConfig {

    private static final Logger logger = LoggerFactory.getLogger(LoginMacRedisConfig.class);
    @Value("1")
    private int logmacDatabaseId;

    @Value("3")
    private int mobmaskDatabaseId;

    @Bean
    public JedisPoolConfig getRedisConfig() {
    JedisPoolConfig config = new JedisPoolConfig();
    config.setMaxIdle(8);
    config.setMinIdle(0);
    return config;
    }

    @Scope(scopeName = "prototype")
    public JedisConnectionFactory jedisConnectionFactory() {

    JedisPoolConfig config = getRedisConfig();
    JedisConnectionFactory factory = new JedisConnectionFactory(config);
    factory.setUsePool(true);
    factory.setHostName(host);
    factory.setPort(port);
    return factory;
    }

    @Bean(name = "login_mac")
    public RedisTemplate<String, Map<String, String>> logmacRedisTemplate() {
    final RedisTemplate<String, Map<String, String>> template = new RedisTemplate<>();

    JedisConnectionFactory jedisConnectionFactory = jedisConnectionFactory();
    jedisConnectionFactory.setDatabase(logmacDatabaseId);
    template.setConnectionFactory(jedisConnectionFactory);
    logger.info("host:{}, port:{}, database:{}", jedisConnectionFactory.getHostName(),jedisConnectionFactory.getPort(), jedisConnectionFactory.getDatabase());

    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    template.setKeySerializer(stringRedisSerializer);
    template.setHashKeySerializer(stringRedisSerializer);
    template.setHashValueSerializer(stringRedisSerializer);
    return template;
    }

    @Bean(name = "mobile_mask")
    public RedisTemplate<String, Map<String, String>> mobileMaskRedisTemplate() {
    final RedisTemplate<String, Map<String, String>> template = new RedisTemplate<>();
    JedisConnectionFactory jedisConnectionFactory = jedisConnectionFactory();
    jedisConnectionFactory.setDatabase(mobmaskDatabaseId);
    template.setConnectionFactory(jedisConnectionFactory);
    logger.info("host:{}, port:{}, database:{}", jedisConnectionFactory.getHostName(),jedisConnectionFactory.getPort(), jedisConnectionFactory.getDatabase());
    StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
    template.setKeySerializer(stringRedisSerializer);
    template.setHashKeySerializer(stringRedisSerializer);
    template.setHashValueSerializer(stringRedisSerializer);
    return template;
    }
}

最后,再写一个Service类,就可以同时注入这两个RedisTemplate,操作同一个Redis服务器上的不同的dbindex了。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * Created by Administrator on 2018/4/10.
 */
@Service
public class RedisTestService {
    @Autowired
    @Qualifier("login_mac")
    private RedisTemplate<String, Map<String, String>> template1;

    @Autowired
    @Qualifier("mobile_mask")
    private RedisTemplate<String, Map<String, String>> template2;

    public void write2Redis() {
    HashOperations<String, String, String> hashOperations = template1.opsForHash();
    Map<String, String> values = new HashMap<>();
    values.put("dbindex", "1");
    hashOperations.putAll("123", values);

    template2.opsForHash().put("123", "dbindex", "3");
    }
}

Application.java 启动类

@SpringBootApplication
public class Application implements CommandLineRunner{
    @Autowired
    private RedisTestService redisTestService;
    public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
    }
    @Override
    public void run(String... strings) throws Exception {
    redisTestService.write2Redis();
    }
}

在redisTestService对象中:有两个RedisTemplate实例:

两个RedisTemplate实例分别封装了两个JedisConnectionFactory:

调试结果下:

2018-04-10 20:18:34.754  INFO 13512 --- [           main] c.y.t.c.redis.LoginMacRedisConfig        : host:192.168.107.253, port:6379, database:1
2018-04-10 20:19:06.972  INFO 13512 --- [           main] c.y.t.c.redis.LoginMacRedisConfig        : host:192.168.107.253, port:6379, database:3

最终查看写入Redis结果,可以看出:dbindex 1 和 dbindex 3 都分别成功写入了数据。

redis 192.168.107.253:6379> SELECT 1
OK
redis 192.168.107.253:6379[1]> KEYS *
1) "123"
redis 192.168.107.253:6379[1]> HGET 123 dbindex
"1"
redis 192.168.107.253:6379[1]> SELECT 3
OK
redis 192.168.107.253:6379[3]> KEYS *
1) "123"
redis 192.168.107.253:6379[3]> HGET 123 dbindex
"3"

额外补充

其实要在同一个应用中访问不同的dbindex,一种方式是使用JedisPool,JedisPool创建Jedis,然后调用select方法选择dbindex。具体实现可参考这篇文章。但这样的话,就不能使用RedisTemplate的各种方便的接口读写Redis了。

    @Bean
    public JedisPool redisPoolFactory() {
        JedisPool jedisPool = new JedisPool(jedisPoolConfig(), host, port);
        Jedis jedis = jedisPool.getResource();
        jedis.select(3);
        return jedisPool;
    }

其实是可以像说的:通过RedisConnectionCommand的 select 方法来选择dbindex的,但是还是同样的问题,用不了RedisTemplate。

RedisConnection redisConnection = redisTemplate.getConnectionFactory().getConnection();
DefaultStringRedisConnection stringRedisConnection = new   DefaultStringRedisConnection(redisConnection);
stringRedisConnection.select(2);
stringRedisConnection.set("test", "test");

另外这里也有一篇Spring Boot Redis多实例配置,也可以参考一下。Spring Boot 兼Redis新手,只能这样了。

原文:http://www.cnblogs.com/hapjin/p/8783084.html

原文地址:https://www.cnblogs.com/hapjin/p/8783084.html

时间: 2024-10-06 22:56:26

Spring boot 使用多个RedisTemplate的相关文章

Spring boot集成Redis(2)—RedisTemplate的使用来存储Map集合

前言:上一篇文章我们用的是StringRedisTemplate,但是它存在一点问题,也迫使我重新写了代码,问题是:在我们往缓存中存入数字形式的String类型时,我们在利用Spring could将获取到的数据发送到另一服务时,我们发现数据已经被强转为Integer类型了,因为我们可能传输的数据庞大,类型多样,为了统一类型,以及开发方便,所以我将缓存改成RedisTemplate这种类型,进行增删改查的操作,文中没有特别举例更新操作,其更新操作与添加操作一样,当key一样时进行添加就会覆盖原v

Spring Boot + spring-data-redis

Redis Redis是缓存, 消息队列, 多种类型的key-value存储服务. Spring Boot Spring Boot为Lettcue和Jedis客户端提供自动注入配置, 并且通过spring-data-redis提供抽象接口 配置连接Redis服务和接口调用 1. 加入依赖 在 pom.xml 的依赖集合中加入 org.springframework.boot:spring-boot-starter-data-reids 依赖, 如下配置 <dependencies> <d

SpringBoot(三) :Spring boot 中 Redis 的使用

前言: 这一篇讲的是Spring Boot中Redis的运用,之前没有在项目中用过Redis,所以没有太大的感觉,以后可能需要回头再来仔细看看. 原文出处: 纯洁的微笑 SpringBoot对常用的数据库支持外,对NoSQL 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结构,例如hashes, lists, sets等,同时支持数据持久化.除此之外,Redis还提供一些类数据库的特性,比如事务,HA,

Spring Boot使用redis实现数据缓存

基于Spring Boot 1.5.2.RELEASE版本,一方面验证与Redis的集成方法,另外了解使用方法. 集成方法 配置依赖 修改pom.xml,增加如下内容. <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> 配置Redis

springboot(三):Spring boot中Redis的使用

spring boot对常用的数据库支持外,对nosql 数据库也进行了封装自动化. redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结构,例如hashes, lists, sets等,同时支持数据持久化.除此之外,Redis还提供一些类数据库的特性,比如事务,HA,主从库.可以说Redis兼具了缓存系统和数据库的一些特性,因此有着丰富的应用场景.本文介绍Redis在Spring Boot中两个典型的应用场景. 如何使用 1.引入

spring 的redis操作类RedisTemplate

spring 集成的redis操作几乎都在RedisTemplate内了. 已spring boot为例, 再properties属性文件内配置好 redis的参数 spring.redis.host=127.0.0.1 spring.redis.port=6379 spring.redis.password=redispass spring.redis.database=0 spring.redis.timeout=5000 再到 Application启动类下加入以下代码: @Bean pu

【redis】spring boot利用redis的Keyspace Notifications实现消息通知

前言 需求:当redis中的某个key失效的时候,把失效时的value写入数据库. github: https://github.com/vergilyn/RedisSamples 1.修改redis.conf 安装的redis服务默认是: notify-keyspace-events "",修改成 notify-keyspace-events Ex; 位置:redis安装目下的redis.windows-service.conf 或 redis.windows.conf.(具体看re

Spring Boot中Redis的使用

软件152   高光顺 redis介绍 Redis是目前业界使用最广泛的内存数据存储.相比memcached,Redis支持更丰富的数据结构,例如hashes, lists, sets等,同时支持数据持久化.除此之外,Redis还提供一些类数据库的特性,比如事务,HA,主从库.可以说Redis兼具了缓存系统和数据库的一些特性,因此有着丰富的应用场景.本文介绍Redis在Spring Boot中两个典型的应用场景. 如何使用 1.引入 spring-boot-starter-redis <depe

Spring Boot 揭秘与实战(二) 数据存储篇 - Redis

文章目录 1. 环境依赖 2. 数据源 2.1. 方案一 使用 Spring Boot 默认配置 2.2. 方案二 手动创建 3. 使用 redisTemplate 操作4. 总结 3.1. 工具类 3.2. 测试类 3.3. 单元测试用例 5. 源代码 本文讲解Spring Boot基础下,如何整合Redis,编写数据访问. 环境依赖 修改 POM 文件,添加 spring-boot-starter-redis 依赖. <dependency> <groupId>org.spri