You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Spring Boot多Redis配置启动报错,需同时使用两个RedisTemplate

Spring Boot多Redis实例配置冲突解决(无需设置Primary)

问题场景

需配置两个独立Redis实例,分别用于Token和Invoice数据存储,已编写InvoiceRedisConfiguration和TokenRedisConfiguration配置类,但启动应用时触发Bean冲突报错。

报错信息

Parameter 0 of method reactiveRedisTemplate in org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration required a single bean, but 2 were found:
    - invoiceRedisFactory: defined by method 'invoiceRedisFactory' in class path resource [tsp/third/party/api/tsp/api/database/connections/invoice/InvoiceRedisConfiguration.class]
    - tokenRedisFactory: defined by method 'tokenRedisFactory' in class path resource [tsp/third/party/api/tsp/api/database/connections/token/TokenRedisConfiguration.class]

原因分析

Spring Boot自动配置类RedisReactiveAutoConfiguration会尝试创建默认ReactiveRedisTemplate,该Bean依赖单个LettuceConnectionFactory实例。由于自定义了两个LettuceConnectionFactoryBean,Spring无法自动选择,导致冲突。

解决方案

1. 排除Redis自动配置类

在Spring Boot启动类中排除RedisReactiveAutoConfiguration,避免自动创建冲突的Reactive模板:

@SpringBootApplication(exclude = RedisReactiveAutoConfiguration.class)
public class YourApplication {
    public static void main(String[] args) {
        SpringApplication.run(YourApplication.class, args);
    }
}

2. 保留自定义配置类(无需修改)

你的配置类已通过@Qualifier明确标记Bean,可直接使用:

InvoiceRedisConfiguration

@Configuration
public class InvoiceRedisConfiguration {
    @Value("${spring.redis.invoice.host:localhost}")
    private String redisHost;

    @Value("${spring.redis.invoice.port:6379}")
    private int redisPort;

    @Bean
    @Qualifier("invoiceRedisFactory")
    public LettuceConnectionFactory invoiceRedisFactory(){
        return new LettuceConnectionFactory(
                new RedisStandaloneConfiguration(redisHost,redisPort)
        );
    }

    @Bean
    @Qualifier("invoiceRedisTemplate")
    public RedisTemplate<String, Invoice> invoiceRedisTemplate(@Qualifier("invoiceRedisFactory") LettuceConnectionFactory invoiceRedisFactory){
        RedisTemplate<String, Invoice> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(invoiceRedisFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(Object.class));
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

TokenRedisConfiguration

@Configuration
public class TokenRedisConfiguration {

    @Value("${spring.redis.host:localhost}")
    private String redisHost;

    @Value("${spring.redis.port:6379}")
    private int redisPort;

    @Bean
    @Qualifier("tokenRedisFactory")
    public LettuceConnectionFactory tokenRedisFactory(){
        return new LettuceConnectionFactory(
                new RedisStandaloneConfiguration(redisHost,redisPort)
        );
    }

    @Bean
    @Qualifier("tokenRedisTemplate")
    public RedisTemplate<String,Token> tokenRedisTemplate(@Qualifier("tokenRedisFactory") LettuceConnectionFactory tokenRedisFactory){
        RedisTemplate<String, Token> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(tokenRedisFactory);
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new Jackson2JsonRedisSerializer<>(Token.class));
        redisTemplate.setHashKeySerializer(new StringRedisSerializer());
        redisTemplate.setHashValueSerializer(new Jackson2JsonRedisSerializer<>(Token.class));
        redisTemplate.afterPropertiesSet();
        return redisTemplate;
    }
}

3. 注入时指定Bean标识

在业务类中通过@Qualifier明确指定要注入的RedisTemplate:

Token业务类示例

@Service
public class TokenService {
    private final RedisTemplate<String, Token> tokenRedisTemplate;

    public TokenService(@Qualifier("tokenRedisTemplate") RedisTemplate<String, Token> tokenRedisTemplate) {
        this.tokenRedisTemplate = tokenRedisTemplate;
    }

    public void saveToken(String key, Token token) {
        tokenRedisTemplate.opsForValue().set(key, token);
    }
}

Invoice业务类示例

@Service
public class InvoiceService {
    private final RedisTemplate<String, Invoice> invoiceRedisTemplate;

    public InvoiceService(@Qualifier("invoiceRedisTemplate") RedisTemplate<String, Invoice> invoiceRedisTemplate) {
        this.invoiceRedisTemplate = invoiceRedisTemplate;
    }

    public void saveInvoice(String key, Invoice invoice) {
        invoiceRedisTemplate.opsForValue().set(key, invoice);
    }
}

说明

排除RedisReactiveAutoConfiguration后,Spring不再自动创建默认Reactive Redis模板,完全使用自定义的两个Redis实例配置,既满足多实例需求,又避免Bean冲突。


内容的提问来源于stack exchange,提问作者Masoud Niki

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 22:09:54