通過RedisTemplate連接多個Redis過程解析
前言
在集群環(huán)境的情況下連接多個Redis數(shù)據(jù)庫是很正常的情況,因為平時都是使用本地環(huán)境的單Redis情況比較多,在這里用代碼總結(jié)一下連接多個數(shù)據(jù)庫的情況(主要是不同ip,同一個ip的不通數(shù)據(jù)庫修改不通地方即可),這里還是使用的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)配置,這里我使用了一個本地的redis數(shù)據(jù)庫,一個遠程的redis數(shù)據(jù)庫,這里只假設(shè)了ip地址不同,其他的配置都相同:
#配置緩存redis spring.redis.database=8 # Redis服務(wù)器地址 spring.redis.host=127.0.0.1 # Redis服務(wù)器連接端口 spring.redis.port=6379 # Redis服務(wù)器連接密碼(默認為空) spring.redis.password= # 連接池最大連接數(shù)(使用負值表示沒有限制) 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數(shù)據(jù)庫地址 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è)置連接超時時間 return factory; } @Bean public RedisTemplate<String, String> redisTemplate(RedisConnectionFactory factory) { StringRedisTemplate template = new StringRedisTemplate(factory); setSerializer(template); //設(shè)置序列化工具,這樣ReportBean不需要實現(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)的時候使用這個來更改序列化方式 /*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數(shù)據(jù)庫連接:
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數(shù)據(jù)庫的例子,在這里還有一個需要注意的是不能將
private RedisTemplate<String,Object> redisTemplate1
代碼中的redisTemplate1修改為redisTemplate,因為這個redisTemplate可能是程序中默認的全局變量,具體的代碼邏輯沒有去查看,如果修改為了redisTemplate的話會出現(xiàn)以下錯誤:
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的連接工廠時,一定要保留一個如下的代碼:
public RedisConnectionFactory redisConnectionFactory()
否則會出現(xiàn)以下錯誤:
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
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java中替代equals,compareTo和toString的方法
這篇文章主要介紹了Java中替代equals,compareTo和toString的方法,文中代碼十分詳細,幫助大家更好的理解的學(xué)習(xí),感興趣的朋友可以了解下2020-06-06多個SpringBoot項目采用redis實現(xiàn)Session共享功能
這篇文章主要介紹了多個SpringBoot項目采用redis實現(xiàn)Session共享,本文通過實例代碼給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-09-09Java接口和抽象類實現(xiàn)抽象和多態(tài)的方法示例
接口和抽象類是 Java 中兩種實現(xiàn)抽象和多態(tài)的方法。它們之間有一些區(qū)別,但也有一些相似之處。這一節(jié)我們將通過詳細的例子來更深入地了解接口和抽象類2023-05-05Java Scala偏函數(shù)與偏應(yīng)用函數(shù)超詳細講解
Scala是一種多范式的編程語言,支持面向?qū)ο蠛秃瘮?shù)式編程。Scala也支持異常處理,即在程序運行過程中發(fā)生意外或錯誤時,采取相應(yīng)的措施2023-04-04