Apollo修改配置文件后运行中的项目使用@ConfigurationProperties的配置实时更新
问题:
apollo动态刷新,应用在@value这种注入方式的属性没有问题,但是如果使用@ConfigurationProperties注解的bean,动态刷新就不好使了,会注入不到的。
解决方法:
方式1:
新建一个监听类。
/**
* Apollo配置监听
*
* @date 2022/9/6 15:16
*/
@Configuration
@Slf4j
public class ApolloChangeListener implements ApplicationContextAware
{
@Autowired
private ApplicationContext applicationContext;
@ApolloConfigChangeListener()
public void refresh(ConfigChangeEvent changeEvent) {
log.info("Apollo配置发生了变化");
for(String changedKey : changeEvent.changedKeys())
{
log.info(changeEvent.changedKeys().toString()+" before refresh:{}",changeEvent.getChange(changedKey).getOldValue());
log.info(changeEvent.changedKeys().toString()+" after refresh:{}",changeEvent.getChange(changedKey).getNewValue());
}
// 刷新的bean
applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
//相关业务处理
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
{
this.applicationContext = applicationContext;
}
}
方式2:
被@ConfigurationProperties修饰的类需要添加如下注解:
@Component
@RefreshScope
新建一个监听类。
/**
* Apollo配置监听
*
* @date 2022/9/6 15:16
*/
@Configuration
@Slf4j
public class ApolloChangeListener
{
@Autowired
private RefreshScope refreshScope;
@ApolloConfigChangeListener()
public void refresh(ConfigChangeEvent changeEvent) {
log.info("Apollo配置发生了变化");
for(String changedKey : changeEvent.changedKeys())
{
log.info(changeEvent.changedKeys().toString()+" before refresh:{}",changeEvent.getChange(changedKey).getOldValue());
log.info(changeEvent.changedKeys().toString()+" after refresh:{}",changeEvent.getChange(changedKey).getNewValue());
}
// 刷新的bean
refreshScope.refreshAll();
//刷新指定的
//refreshScope.refresh("myConfig");
//相关业务处理
}
}
说明:
@ApolloConfigChangeListener()注解中可填写参数
interestedKeyPrefixes:指定监听的配置属性前缀。当在Apollo配置中心修改配置,配置发生变化的前缀是所填值,那么就执行带有@ApolloConfigChangeListener()注解方法
value:指定监听的配置文件。
注:如果不填写属性值,默认是只要发生变化都执行方法
例子:@ApolloConfigChangeListener(value = "application.yml", interestedKeyPrefixes = "my.config.")
例子说明:当在Apollo配置中心,修改application.yml下的,前缀为my.config的属性时,触发刷新方法执行。
额外说明:
有时候,动态刷新成功后,发现有些调用相关接口执行还是原配置的效果,没成功(比如某个花钱的配置属性的环境切换,pro改为test,调用相关接口发现执行时属性还是pro时的效果)。
那有可能是因为涉及到配置类启动时初始化的问题,比如说,有个注入到spring容器的配置类(@Configuration@bean)刚好用到你这个带有@ConfigurationProperties类在项目启动进行初始化。项目启动后,已经注入到了spring容器中,你动态刷新的配置属性值,但是没有去把容器中的这个配置类再次刷新,那么配置类还是原来的配置类,里面的属性也还是原来的。
解决方法:在上面//相关业务处理
下面,也就是配置动态刷新后,再次初始化一下spring容器中的那个配置类,就能生效成功了。
(可能表达的不是很好。。。,说白了可能就是调用到相关配置属性另一个bean没有刷新)
参考:https://blog.csdn.net/luo15242208310/article/details/115521686