通過(guò)RedisTemplate連接多個(gè)Redis過(guò)程解析
前言
在集群環(huán)境的情況下連接多個(gè)Redis數(shù)據(jù)庫(kù)是很正常的情況,因?yàn)槠綍r(shí)都是使用本地環(huán)境的單Redis情況比較多,在這里用代碼總結(jié)一下連接多個(gè)數(shù)據(jù)庫(kù)的情況(主要是不同ip,同一個(gè)ip的不通數(shù)據(jù)庫(kù)修改不通地方即可),這里還是使用的springboot提供的spring-boot-starter-data-redis工具包,具體介紹如下:
1.引入redis相關(guān)的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文件中設(shè)置redis相關(guān)配置,這里我使用了一個(gè)本地的redis數(shù)據(jù)庫(kù),一個(gè)遠(yuǎn)程的redis數(shù)據(jù)庫(kù),這里只假設(shè)了ip地址不同,其他的配置都相同:
#配置緩存redis spring.redis.database=8 # Redis服務(wù)器地址 spring.redis.host=127.0.0.1 # Redis服務(wù)器連接端口 spring.redis.port=6379 # Redis服務(wù)器連接密碼(默認(rèn)為空) spring.redis.password= # 連接池最大連接數(shù)(使用負(fù)值表示沒(méi)有限制) spring.redis.pool.max-active=8 # 連接池最大阻塞等待時(shí)間(使用負(fù)值表示沒(méi)有限制) spring.redis.pool.max-wait=-1 # 連接池中的最大空閑連接 spring.redis.pool.max-idle=8 # 連接池中的最小空閑連接 spring.redis.pool.min-idle=0 # 連接超時(shí)時(shí)間(毫秒) spring.redis.keytimeout=1000 spring.redis.timeout=0 #配置第二個(gè)redis數(shù)據(jù)庫(kù)地址 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); //設(shè)置連接超時(shí)時(shí)間
return factory;
}
@Bean
public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate(factory);
setSerializer(template); //設(shè)置序列化工具,這樣ReportBean不需要實(shí)現(xiàn)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的數(shù)據(jù)結(jié)構(gòu)的時(shí)候使用這個(gè)來(lái)更改序列化方式
/*RedisSerializer<String> stringSerializer = new StringRedisSerializer();
template.setKeySerializer(stringSerializer );
template.setValueSerializer(stringSerializer );
template.setHashKeySerializer(stringSerializer );
template.setHashValueSerializer(stringSerializer );*/
}
}
4.App啟動(dòng)類:
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.測(cè)試多個(gè)Redis數(shù)據(jù)庫(kù)連接:
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個(gè)Redis數(shù)據(jù)庫(kù)的例子,在這里還有一個(gè)需要注意的是不能將
private RedisTemplate<String,Object> redisTemplate1
代碼中的redisTemplate1修改為redisTemplate,因?yàn)檫@個(gè)redisTemplate可能是程序中默認(rèn)的全局變量,具體的代碼邏輯沒(méi)有去查看,如果修改為了redisTemplate的話會(huì)出現(xiàn)以下錯(cuò)誤:
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
如果在設(shè)置RedisConnectionFactory的連接工廠時(shí),一定要保留一個(gè)如下的代碼:
public RedisConnectionFactory redisConnectionFactory()
否則會(huì)出現(xiàn)以下錯(cuò)誤:
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
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Spring boot項(xiàng)目redisTemplate實(shí)現(xiàn)輕量級(jí)消息隊(duì)列的方法
- 在Java中使用redisTemplate操作緩存的方法示例
- Spring Boot單元測(cè)試中使用mockito框架mock掉整個(gè)RedisTemplate的示例
- Redis Template實(shí)現(xiàn)分布式鎖的實(shí)例代碼
- Spring學(xué)習(xí)筆記之RedisTemplate的配置與使用教程
- spring整合redis以及使用RedisTemplate的方法
- spring使用RedisTemplate的操作類訪問(wèn)Redis
- 如何解決redisTemplate注入為空問(wèn)題
相關(guān)文章
Java中替代equals,compareTo和toString的方法
這篇文章主要介紹了Java中替代equals,compareTo和toString的方法,文中代碼十分詳細(xì),幫助大家更好的理解的學(xué)習(xí),感興趣的朋友可以了解下2020-06-06
多個(gè)SpringBoot項(xiàng)目采用redis實(shí)現(xiàn)Session共享功能
這篇文章主要介紹了多個(gè)SpringBoot項(xiàng)目采用redis實(shí)現(xiàn)Session共享,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
Java接口和抽象類實(shí)現(xiàn)抽象和多態(tài)的方法示例
接口和抽象類是 Java 中兩種實(shí)現(xiàn)抽象和多態(tài)的方法。它們之間有一些區(qū)別,但也有一些相似之處。這一節(jié)我們將通過(guò)詳細(xì)的例子來(lái)更深入地了解接口和抽象類2023-05-05
Java靜態(tài)代碼塊加載驅(qū)動(dòng)代碼實(shí)例
這篇文章主要介紹了Java靜態(tài)代碼塊加載驅(qū)動(dòng)代碼實(shí)例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-07-07
利用Java代碼寫(xiě)一個(gè)并行調(diào)用模板
這篇文章主要介紹了利用Java代碼寫(xiě)一個(gè)并行調(diào)用模板,文章基于Java的相關(guān)內(nèi)容展開(kāi)寫(xiě)一個(gè)并行調(diào)用模板的詳細(xì)介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-05-05
PHP Laravel實(shí)現(xiàn)文件下載功能
本文重點(diǎn)給大家介紹Laravel實(shí)現(xiàn)文件下載功能的實(shí)例代碼,需要的朋友參考下吧2017-09-09
Java Scala偏函數(shù)與偏應(yīng)用函數(shù)超詳細(xì)講解
Scala是一種多范式的編程語(yǔ)言,支持面向?qū)ο蠛秃瘮?shù)式編程。Scala也支持異常處理,即在程序運(yùn)行過(guò)程中發(fā)生意外或錯(cuò)誤時(shí),采取相應(yīng)的措施2023-04-04

