JAVA语言之Spring boot 使用多个RedisTemplate
小标 2018-07-19 来源 : 阅读 1328 评论 0

摘要:本文主要向大家介绍了JAVA语言之Spring boot 使用多个RedisTemplate,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

本文主要向大家介绍了JAVA语言之Spring boot 使用多个RedisTemplate,通过具体的内容向大家展示,希望对大家学习JAVA语言有所帮助。

问题描述

想在一个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. */

@Configurationpublic 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. */@Servicepublic 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 启动类

@SpringBootApplicationpublic 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");

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注编程语言JAVA频道!

本文由 @小标 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程