背景
在使用spring boot 2.x做项目的时候,需要访问多个数据库db,本博客讲进行实战展示
实战
思路:每一个redisTemplate实例只能访问一个对应的db,所以我们需要做多个redisTemplate实例,并且每个实例必须有自己对应的连接工厂。
package com.ztjy.contentrank.common;
import com.alibaba.fastjson.parser.ParserConfig;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ztjy.parent.redis.FastJson2JsonRedisSerializer;
import com.ztjy.parent.redis.RedisProperties;
import com.ztjy.tool.StringUtils;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.redis.connection.RedisPassword;
import org.springframework.data.redis.connection.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceClientConfiguration;
import org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.connection.lettuce.LettucePoolingClientConfiguration;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import java.time.Duration;
@Log4j2
@SuppressWarnings("unchecked")
public class MyRedisAutoConfiguration {
@Autowired
private MyServerProperties myServerProperties;
@Autowired
private RedisProperties redisProperties;
static {
ParserConfig.getGlobalInstance().addAccept("com.xxxx");
}
private RedisTemplate redisTemplateMaker(LettuceConnectionFactory lettuceConnectionFactory) {
RedisTemplate redisTemplate = new RedisTemplate();
redisTemplate.setConnectionFactory(lettuceConnectionFactory);
//使用Jackson2JsonRedisSerializer来序列化和反序列化redis的value值
FastJson2JsonRedisSerializer<Object> fastJsonRedisSerializer = new FastJson2JsonRedisSerializer<>(Object.class);
ObjectMapper mapper = new ObjectMapper();
mapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
mapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
fastJsonRedisSerializer.setObjectMapper(mapper);
//使用StringRedisSerializer来序列化和反序列化redis的key值
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(fastJsonRedisSerializer);
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(fastJsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
@Bean(name = "recallRedisTemplate")
public RedisTemplate recallRedisTemplate(@Qualifier(value = "recallLettuceConnectionFactory") LettuceConnectionFactory recallLettuceConnectionFactory) {
return redisTemplateMaker(recallLettuceConnectionFactory);
}
@Bean(name = "portraitRedisTemplate")
public RedisTemplate portraitRedisTemplate(@Qualifier(value = "portraitLettuceConnectionFactory") LettuceConnectionFactory portraitLettuceConnectionFactory) {
return redisTemplateMaker(portraitLettuceConnectionFactory);
}
@Bean(value = "recallLettuceConnectionFactory")
@Primary
public LettuceConnectionFactory recallLettuceConnectionFactory(
@Qualifier(value = "genericObjectPoolConfig") GenericObjectPoolConfig genericObjectPoolConfig) {
LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration
.builder()
.commandTimeout(Duration.ofMillis(this.redisProperties.getTimeout()))
.poolConfig(genericObjectPoolConfig)
.build();
return new LettuceConnectionFactory(redisStandaloneConfiguration(myServerProperties.getRedis().getRecallDb()), clientConfig);
}
@Bean(value = "portraitLettuceConnectionFactory")
public LettuceConnectionFactory portraitLettuceConnectionFactory(
@Qualifier(value = "genericObjectPoolConfig") GenericObjectPoolConfig genericObjectPoolConfig) {
LettuceClientConfiguration clientConfig = LettucePoolingClientConfiguration
.builder()
.commandTimeout(Duration.ofMillis(this.redisProperties.getTimeout()))
.poolConfig(genericObjectPoolConfig)
.build();
return new LettuceConnectionFactory(redisStandaloneConfiguration(myServerProperties.getRedis().getPortraitDb()), clientConfig);
}
private RedisStandaloneConfiguration redisStandaloneConfiguration(int db) {
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration();
config.setHostName(redisProperties.getHost());
if (StringUtils.isNotBlank(redisProperties.getPassword())) {
config.setPassword(RedisPassword.of(redisProperties.getPassword()));
}
config.setPort(redisProperties.getPort());
config.setDatabase(db);
return config;
}
}
在使用的时候,只需要注入对应名称的redisTemplate就可以了。
@Autowired
@Qualifier(value = "recallRedisTemplate")
private RedisTemplate recallRedisTemplate;
@Autowired
@Qualifier(value = "portraitRedisTemplate")
private RedisTemplate portraitRedisTemplate;
评价
注意:
- 主工厂bean需要添加@primary
- 每个redisTemplate需要有自己对应的工厂bean来设置对应的db