背景
在使用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