@refreshscope 无法直接刷新 redis 连接工厂,因其由自动配置声明为单例且未被包裹;需禁用 redisautoconfiguration,手动定义 @refreshscope 的连接工厂及 stringredistemplate 并通过 /actuator/refresh 触发刷新。

@RefreshScope 本身不能直接刷新 Redis 连接工厂(JedisConnectionFactory 或 LettuceConnectionFactory),因为 Spring Boot 的 Redis 自动配置类(如 RedisAutoConfiguration)默认把 RedisConnectionFactory 声明为 @Singleton,且未被 @RefreshScope 包裹 —— 所以即使你给某个业务 Bean 加了 @RefreshScope,它持有的 StringRedisTemplate 仍复用旧的连接工厂,配置变更不会生效。
为什么直接加 @RefreshScope 到 @Configuration 类无效
很多人尝试在 Redis 配置类上加 @RefreshScope,比如:
@Configuration
@RefreshScope
public class RedisConfig {
@Bean
public RedisConnectionFactory redisConnectionFactory() { ... }
}
这行不通,原因有三:
Redis 缓存和数据结构管理技能。通过自然语言操作 Redis,支持 String、Hash、List、Set、ZSet、Stream 等数据结构操作。当用户提到 Redis、缓存、消息队列、会话存储时使用此技能。
-
@Bean方法在@Configuration类中默认由 CGLIB 代理增强,而@RefreshScope的代理机制与之冲突,Spring 会忽略该注解 -
RedisConnectionFactory是被多个底层组件(如RedisTemplate、StringRedisTemplate)强依赖的基础设施 Bean,它的生命周期由自动配置控制,不是普通业务 Bean - 即使强行代理成功,销毁并重建
RedisConnectionFactory会导致所有正在使用的连接被强制关闭,可能引发Connection reset或Cannot get Jedis connection异常
真正可行的刷新路径:绕过自动配置,手管连接工厂
核心思路是放弃 Spring Boot 默认的 RedisAutoConfiguration,自己定义可刷新的连接工厂 Bean,并确保它被所有 Redis 操作模板正确引用。实操要点如下:
- 在
application.yml中禁用自动配置:spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration - 定义一个
@RefreshScope的配置类,暴露RedisConnectionFactory和StringRedisTemplate:
@Configuration
public class DynamicRedisConfig {
@Value("${redis.host:localhost}")
private String host;
@Value("${redis.port:6379}")
private int port;
@Value("${redis.password:}")
private String password;
@Bean
@RefreshScope
public RedisConnectionFactory redisConnectionFactory() {
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
.commandTimeout(Duration.ofSeconds(5))
.build();
RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(host, port);
if (!password.isEmpty()) {
config.setPassword(RedisPassword.of(password));
}
return new LettuceConnectionFactory(config, clientConfig);
}
@Bean
@RefreshScope
public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory factory) {
StringRedisTemplate template = new StringRedisTemplate();
template.setConnectionFactory(factory);
template.afterPropertiesSet(); // 必须调用,否则序列化器未初始化
return template;
}
}
- 确保所有注入点都使用
@Autowired引用StringRedisTemplate(而非RedisTemplate<object object></object>等泛型变体),避免因类型匹配导致注入了自动配置遗留的旧实例 - 刷新时必须触发
/actuator/refresh,且新配置需已写入配置源(如 Nacos、Apollo 或本地application.yml)
集群或哨兵模式下刷新的特殊处理
如果你用的是 Redis 哨兵或集群,RedisStandaloneConfiguration 不适用,需改用对应配置类:
- 哨兵模式:
RedisSentinelConfiguration,注意setMaster和setSentinels必须每次重建时重新设置 - 集群模式:
RedisClusterConfiguration,传入Set<redisnode></redisnode>,节点列表变更后需完整重建连接工厂 - 所有配置类字段(如密码、超时、SSL 开关)都应通过
@Value注入,且确保它们能被@RefreshScope捕获 —— 避免硬编码或静态 final 常量
最易被忽略的一点:Lettuce 连接池(GenericObjectPoolConfig)本身不支持运行时刷新,所以如果要动态调大 max-total,必须连同整个 RedisConnectionFactory 一起重建 —— 这意味着连接池参数也得纳入 @Value 管理。










