冲突源于自动配置打架、Bean名称/类型重叠及连接工厂混用;核心解法是隔离连接工厂、显式命名Bean、排除冗余依赖,确保RedissonClient与RedisTemplate分别使用各自适配的连接工厂,避免混用导致命令不识别或StackOverflowError。

直接结论:冲突不是代码写错了,而是自动配置打架 + Bean 名称/类型重叠 + 连接工厂混用导致的。核心解法是「隔离连接工厂」+「显式命名 Bean」+「排除冗余依赖」。
Redisson 自动配置会覆盖 RedisConnectionFactory
redisson-spring-boot-starter 默认会注册自己的 RedissonConnectionFactory,并把它声明为 @Primary。一旦它被 Spring 容器选中,所有没指定 @Qualifier 的 RedisTemplate 构造函数参数(比如 RedisTemplate(RedisConnectionFactory))就会注入这个 Redisson 版本的工厂——但它不支持 ZSet、HyperLogLog 等原生命令,调用 opsForZSet().add() 就会触发 StackOverflowError。
常见错误现象:
-
java.lang.StackOverflowError出现在redisTemplate.opsForZSet().add()调用时 -
RedisTemplate执行set正常,但zadd报错或卡死 - 启动日志里出现
Bean 'redissonConnectionFactory' is defined in null类似提示
实操建议:
- 删掉
@Bean方法里对RedissonConnectionFactory的字段注入(比如@Autowired private RedissonConnectionFactory),它会引发循环依赖 - 改用
LettuceConnectionFactory专门配一个RedisTemplate:@Bean("lettuceRedisTemplate") public RedisTemplate<String, Object> lettuceRedisTemplate(RedisConnectionFactory factory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(factory); // 这个 factory 必须是 Lettuce 的 template.setKeySerializer(new StringRedisSerializer()); template.setValueSerializer(new GenericJackson2JsonRedisSerializer()); template.afterPropertiesSet(); return template; } - 确保该
RedisConnectionFactoryBean 明确来自spring-boot-starter-data-redis,而不是 redisson starter
多个 RedisTemplate Bean 导致 @Autowired 失效
Spring 容器里如果存在多个 RedisTemplate<string object></string> 类型的 Bean(比如你自定义了一个,又没关掉 Spring Boot 的默认 redisTemplate),@Autowired 就会报 NoUniqueBeanDefinitionException。
实操建议:
- 给自定义
RedisTemplate显式命名:@Bean("myRedisTemplate") - 注入时必须带上
@Qualifier("myRedisTemplate"):@Autowired @Qualifier("myRedisTemplate") private RedisTemplate<String, Object> redisTemplate; - 保留原生
StringRedisTemplate(bean name 是stringRedisTemplate),它不受影响,可继续用@Qualifier("stringRedisTemplate")注入 - 避免在同一个配置类里反复声明同类型
@Bean方法却不加name或@Primary
spring-data-redis 版本冲突引发启动失败
IllegalStateException: Error processing condition 这类启动异常,90% 是因为 Maven 拉进了两个不同版本的 spring-data-redis:一个来自 spring-boot-starter-data-redis,另一个来自 redisson-spring-boot-starter(它自带一个旧版或新版传递依赖)。
实操建议:
- 用 IDEA 打开
pom.xml→ 底部切到Dependency Analyzer→Conflicts标签页,找标红的org.springframework.data:spring-data-redis - 执行
mvn dependency:tree -Dincludes=org.springframework.data:spring-data-redis确认实际加载的版本 - 在
redisson-spring-boot-starter依赖块里加<exclusions></exclusions>排除它的spring-data-redis:<dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.23.3</version> <exclusions> <exclusion> <groupId>org.springframework.data</groupId> <artifactId>spring-data-redis</artifactId> </exclusion> </exclusions> </dependency> - 同时检查
commons-pool2和jedis是否也被多版本引入,一并排除
RedissonClient 和 RedisTemplate 共用同一套连接参数但不能共用连接工厂
很多人想“复用配置”,于是把 RedissonClient 和 RedisTemplate 都指向同一个 RedisConnectionFactory,这是错的。Redisson 的连接工厂和 Lettuce/Jedis 的连接工厂实现完全不同,强行混用会导致序列化错乱、命令不识别、连接泄漏等问题。
实操建议:
- Redisson 用
RedissonClient实例,通过spring.redisson.config或手动加载Config对象初始化 - RedisTemplate 用
LettuceConnectionFactory,从spring.redis.*配置自动构建 - 两个客户端各自维护连接池,不要试图共享
ConnectionFactory实例 - 如果要用 YAML 内联配置 Redisson,别写
spring.redisson.config: |—— 某些 starter 版本根本不识别这个语法,老老实实用spring.redisson.file=redisson.yml
最易被忽略的一点:Redisson 的 RedissonConnectionFactory 不是标准 Spring Data Redis 的扩展,它是个“假工厂”,只代理了部分操作;而 RedisTemplate 的全部能力依赖真实 Lettuce/Jedis 实现。混淆这两者,比版本冲突更难定位。


















