首页 > 编程 > Java > 正文

通过RedisTemplate连接多个Redis过程解析

2019-11-26 08:41:30
字体:
来源:转载
供稿:网友

 前言

在集群环境的情况下连接多个Redis数据库是很正常的情况,因为平时都是使用本地环境的单Redis情况比较多,在这里用代码总结一下连接多个数据库的情况(主要是不同ip,同一个ip的不通数据库修改不通地方即可),这里还是使用的springboot提供的spring-boot-starter-data-redis工具包,具体介绍如下:

1.引入redis相关的jar

<parent>     <groupId>org.springframework.boot</groupId>     <artifactId>spring-boot-starter-parent</artifactId>     <version>1.5.6.RELEASE</version>   </parent>    <dependencies>     <dependency>       <groupId>org.springframework.boot</groupId>       <artifactId>spring-boot-starter-data-redis</artifactId>     </dependency>      <dependency>       <groupId>org.springframework.boot</groupId>       <artifactId>spring-boot-starter-test</artifactId>     </dependency>      <dependency>       <groupId>org.springframework.boot</groupId>       <artifactId>spring-boot-starter-web</artifactId>     </dependency>       <dependency>       <groupId>org.springframework.boot</groupId>       <artifactId>spring-boot-configuration-processor</artifactId>       <optional>true</optional>     </dependency>   </dependencies> 

2.在配置文件application.properties文件中设置redis相关配置,这里我使用了一个本地的redis数据库,一个远程的redis数据库,这里只假设了ip地址不同,其他的配置都相同:

#配置缓存redis spring.redis.database=8 # Redis服务器地址 spring.redis.host=127.0.0.1 # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器连接密码(默认为空) spring.redis.password= # 连接池最大连接数(使用负值表示没有限制) spring.redis.pool.max-active=8 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.pool.max-wait=-1 # 连接池中的最大空闲连接 spring.redis.pool.max-idle=8 # 连接池中的最小空闲连接 spring.redis.pool.min-idle=0 # 连接超时时间(毫秒) spring.redis.keytimeout=1000 spring.redis.timeout=0 #配置第二个redis数据库地址 spring.redis.host2=172.19.3.150 

3.添加RedisTemplate的Bean:

import com.fasterxml.jackson.annotation.JsonAutoDetect; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.autoconfigure.EnableAutoConfiguration; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.RedisConnectionFactory; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.data.redis.core.StringRedisTemplate; import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import org.springframework.data.redis.serializer.StringRedisSerializer; import redis.clients.jedis.JedisPoolConfig;  /**  * @author liaoyubo  * @version 1.0 2017/8/1  * @description  */ @Configuration public class RedisConfig {    @Value("${spring.redis.host}")   private String hostName;   @Value("${spring.redis.port}")   private int port;   @Value("${spring.redis.password}")   private String passWord;   @Value("${spring.redis.pool.max-idle}")   private int maxIdl;   @Value("${spring.redis.pool.min-idle}")   private int minIdl;   @Value("${spring.redis.database}")   private int database;   @Value("${spring.redis.keytimeout}")   private long keytimeout;   @Value("${spring.redis.timeout}")   private int timeout;   @Value("${spring.redis.host2}")   private String hostName2;    /*@Bean   public JedisConnectionFactory redisConnectionFactory() {     JedisConnectionFactory factory = new JedisConnectionFactory();     factory.setHostName(hostName);     factory.setPort(port);     factory.setTimeout(timeout); //设置连接超时时间     return factory;   }    @Bean   public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {     StringRedisTemplate template = new StringRedisTemplate(factory);     setSerializer(template); //设置序列化工具,这样ReportBean不需要实现Serializable接口     template.afterPropertiesSet();     return template;   }   private void setSerializer(StringRedisTemplate template) {     Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);     ObjectMapper om = new ObjectMapper();     om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);     om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);     jackson2JsonRedisSerializer.setObjectMapper(om);     template.setValueSerializer(jackson2JsonRedisSerializer);   }*/    @Bean   public RedisConnectionFactory redisConnectionFactory(){     JedisPoolConfig poolConfig=new JedisPoolConfig();     poolConfig.setMaxIdle(maxIdl);     poolConfig.setMinIdle(minIdl);     poolConfig.setTestOnBorrow(true);     poolConfig.setTestOnReturn(true);     poolConfig.setTestWhileIdle(true);     poolConfig.setNumTestsPerEvictionRun(10);     poolConfig.setTimeBetweenEvictionRunsMillis(60000);     JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(poolConfig);     jedisConnectionFactory.setHostName(hostName);     if(!passWord.isEmpty()){       jedisConnectionFactory.setPassword(passWord);     }     jedisConnectionFactory.setPort(port);     jedisConnectionFactory.setDatabase(database);     return jedisConnectionFactory;   }    @Bean   public RedisConnectionFactory redisConnectionFactory2(){     JedisPoolConfig poolConfig=new JedisPoolConfig();     poolConfig.setMaxIdle(maxIdl);     poolConfig.setMinIdle(minIdl);     poolConfig.setTestOnBorrow(true);     poolConfig.setTestOnReturn(true);     poolConfig.setTestWhileIdle(true);     poolConfig.setNumTestsPerEvictionRun(10);     poolConfig.setTimeBetweenEvictionRunsMillis(60000);     JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(poolConfig);     jedisConnectionFactory.setHostName(hostName2);     if(!passWord.isEmpty()){       jedisConnectionFactory.setPassword(passWord);     }     jedisConnectionFactory.setPort(port);     jedisConnectionFactory.setDatabase(database);     return jedisConnectionFactory;   }    @Bean(name = "redisTemplate1")   public RedisTemplate<String, Object> redisTemplateObject() throws Exception {     RedisTemplate<String, Object> redisTemplateObject = new RedisTemplate<String, Object>();     redisTemplateObject.setConnectionFactory(redisConnectionFactory());     setSerializer(redisTemplateObject);     redisTemplateObject.afterPropertiesSet();     return redisTemplateObject;   }    @Bean(name = "redisTemplate2")   public RedisTemplate<String, Object> redisTemplateObject2() throws Exception {     RedisTemplate<String, Object> redisTemplateObject = new RedisTemplate<String, Object>();     redisTemplateObject.setConnectionFactory(redisConnectionFactory2());     setSerializer(redisTemplateObject);     redisTemplateObject.afterPropertiesSet();     return redisTemplateObject;   }    private void setSerializer(RedisTemplate<String, Object> template) {     Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(         Object.class);     ObjectMapper om = new ObjectMapper();     om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);     om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);     jackson2JsonRedisSerializer.setObjectMapper(om);     template.setKeySerializer(template.getStringSerializer());     template.setValueSerializer(jackson2JsonRedisSerializer);     template.setHashValueSerializer(jackson2JsonRedisSerializer);     //在使用String的数据结构的时候使用这个来更改序列化方式     /*RedisSerializer<String> stringSerializer = new StringRedisSerializer();     template.setKeySerializer(stringSerializer );     template.setValueSerializer(stringSerializer );     template.setHashKeySerializer(stringSerializer );     template.setHashValueSerializer(stringSerializer );*/    }  } 

4.App启动类:

import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;  /**  * @author liaoyubo  * @version 1.0 2017/7/31  * @description  */ @SpringBootApplication public class App {    public static void main(String [] args){     SpringApplication.run(App.class);   }  } 

5.测试多个Redis数据库连接:

import com.springRedis.App; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.dao.DataAccessException; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.core.RedisCallback; import org.springframework.data.redis.core.RedisTemplate; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource;  /**  * @author liaoyubo  * @version 1.0 2017/7/31  * @description  */  @RunWith(SpringRunner.class) @SpringBootTest(classes = App.class) public class PipelineTest {    @Autowired   @Resource(name = "redisTemplate1")   private RedisTemplate<String,Object> redisTemplate1;    @Autowired   @Resource(name = "redisTemplate2")   private RedisTemplate<String,Object> redisTemplate2;    @Test   public void testPipeLine(){     redisTemplate1.opsForValue().set("a",1);     redisTemplate1.opsForValue().set("b",2);     /*redisTemplate1.executePipelined(new RedisCallback<Object>() {       @Override       public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {         redisConnection.openPipeline();         for (int i = 0;i < 10;i++){           redisConnection.incr("a".getBytes());         }         System.out.println("a:"+redisTemplate1.opsForValue().get("a"));         redisTemplate1.opsForValue().set("c",3);         for(int j = 0;j < 20;j++){           redisConnection.incr("b".getBytes());         }         System.out.println("b:"+redisTemplate1.opsForValue().get("b"));         System.out.println("c:"+redisTemplate1.opsForValue().get("c"));         redisConnection.closePipeline();         return null;       }     });*/     System.out.println("b:"+redisTemplate1.opsForValue().get("b"));     System.out.println("a:"+redisTemplate1.opsForValue().get("a"));      redisTemplate2.opsForValue().set("m",5);     redisTemplate2.opsForValue().set("n",6);     System.out.println("m:"+redisTemplate2.opsForValue().get("m"));     System.out.println("n:"+redisTemplate2.opsForValue().get("n"));   } 

以上就是连接2个Redis数据库的例子,在这里还有一个需要注意的是不能将

private RedisTemplate<String,Object> redisTemplate1 

代码中的redisTemplate1修改为redisTemplate,因为这个redisTemplate可能是程序中默认的全局变量,具体的代码逻辑没有去查看,如果修改为了redisTemplate的话会出现以下错误:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.data.redis.core.RedisTemplate<?, ?>' available: expected single matching bean but found 2: redisTemplate1,redisTemplate2   at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:173)   at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)   at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)   at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:585)   ... 33 more 

如果在设置RedisConnectionFactory的连接工厂时,一定要保留一个如下的代码:

public RedisConnectionFactory redisConnectionFactory() 

否则会出现以下错误:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'org.springframework.data.redis.connection.RedisConnectionFactory' available: expected single matching bean but found 2: redisConnectionFactory1,redisConnectionFactory2   at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:173)   at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1116)   at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1066)   at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:835)   at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:741)   ... 47 more 

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持武林网。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表