Spring Boot中通过@Profile声明独立的单机/集群RedisConnectionFactory Bean,配合spring.profiles.active自动切换;RedisTemplate构造器参数自动注入当前激活profile的工厂,无需@Qualifier。

Spring Boot里怎么让RedisConnectionFactory按环境自动换?
靠@Profile + 条件化Bean注册,不是靠硬编码判断环境名。Spring Boot本身不自动切换工厂,得手动把单机和集群的RedisConnectionFactory声明成两个独立Bean,并用@Profile("standalone")和@Profile("cluster")区隔开。
关键点是:这两个Bean不能同名,否则启动报BeanDefinitionOverrideException;同时要确保只有一份生效,所以必须显式关闭spring.main.allow-bean-definition-overriding=false(默认值,别动)。
-
@Configuration类里分别写两个@Bean方法,各自加@Profile - 单机版用
LettuceConnectionFactory配RedisStandaloneConfiguration - 集群版用
LettuceConnectionFactory配RedisClusterConfiguration - 别忘了在
application.yml里通过spring.profiles.active指定当前激活的profile
为什么RedisTemplate不能直接@Autowired两个工厂?
因为RedisTemplate本身不是条件Bean,它依赖RedisConnectionFactory——而Spring容器只会注入那个被激活profile匹配的工厂实例。你不需要、也不应该在代码里“选工厂”,而是让RedisTemplate始终引用一个名字固定的RedisConnectionFactory Bean,由Spring完成解析。
常见错误是写两个@Autowired RedisConnectionFactory字段,还加@Qualifier,这反而破坏了profile隔离逻辑。正确做法是:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
- 只声明一个
@Bean public RedisTemplate<string object> redisTemplate(RedisConnectionFactory factory)</string> - 这个
factory参数会自动绑定到当前激活profile下的那个RedisConnectionFactoryBean - 不用
@Qualifier,除非你真有多个同类型Bean且都处于激活状态(那说明profile配置错了)
集群配置连不上?检查RedisClusterConfiguration初始化方式
用RedisClusterConfiguration时,节点列表必须是Set<redisnode></redisnode>,不是字符串数组。很多人直接传"127.0.0.1:7000,127.0.0.1:7001",结果抛IllegalArgumentException: nodes must not be empty。
实操建议:
- 从
spring.redis.cluster.nodes读取字符串后,用Arrays.stream().map(s -> s.split(":")).map(parts -> new RedisNode(parts[0], Integer.parseInt(parts[1]))).collect(Collectors.toSet())构造 - 别漏掉
spring.redis.password(如果集群启了认证),它不会自动进RedisClusterConfiguration,得手动设setPassword(RedisPassword.of(...)) - 连接超时、重试次数这些Lettuce底层参数,统一配在
LettuceClientConfiguration里,别分散在各处
Profile切过去但Redis操作还是走老连接?可能是缓存没清
开发时反复改spring.profiles.active,发现Redis请求没切到新配置,大概率是IDE或构建工具缓存了旧的ApplicationContext。Spring Boot DevTools不会自动重载profile变更,需要手动触发刷新。
更隐蔽的问题是:某些第三方starter(比如Spring Session Redis)内部也持有RedisConnectionFactory引用,它们可能在应用上下文刷新前就初始化完了。这时候即使你profile切对了,Session模块还在用旧连接。
- 启动时看日志里有没有
Creating shared instance of singleton bean 'redisConnectionFactory',确认是哪个profile下的Bean被创建了 - 加
@DependsOn("redisConnectionFactory")强制依赖顺序(仅限自定义组件) - 集群模式下务必关掉
spring.session.redis.shutdown-timeout(默认30s),避免停机时等不到集群响应卡住

















