在我之前的博客中我 已经介绍了Apollo配置中心 结合springboot 是如何操作的了。有需要的朋友可以查看我的上一个博文
https://blog.csdn.net/HiBoyljw/article/details/86495531
我们都知道,springboot中的配置文件中的配置属性丢到Apollo之后,我们在Apollo中修改属性 那么应用就能够自动刷新了。但是其中有一个却需要我们的手动去操作那就是ConfigurationProperties 这个在关网中是这样介绍的
Spring Boot提供了@ConfigurationProperties把配置注入到bean对象中。
Apollo也支持这种方式,下面的例子会把redis.cache.expireSeconds和redis.cache.commandTimeout分别注入到SampleRedisConfig的expireSeconds和commandTimeout字段中。
@ConfigurationProperties(prefix = "redis.cache")
public class SampleRedisConfig {
private int expireSeconds;
private int commandTimeout;
public void setExpireSeconds(int expireSeconds) {
this.expireSeconds = expireSeconds;
}
public void setCommandTimeout(int commandTimeout) {
this.commandTimeout = commandTimeout;
}
}
在Configuration类中按照下面的方式使用(假设应用默认的application namespace中有redis.cache.expireSeconds和redis.cache.commandTimeout的配置项):
@Configuration
@EnableApolloConfig
public class AppConfig {
@Bean
public SampleRedisConfig sampleRedisConfig() {
return new SampleRedisConfig();
}
}
需要注意的是,@ConfigurationProperties如果需要在Apollo配置变化时自动更新注入的值,需要配合使用EnvironmentChangeEvent或RefreshScope。
这就意味着如果我们使用了@ConfigurationProperties 这种属性来读取配置文件的话 我们是需要 在类上加一个@RefreshScope才行。但是有些时候我们是要去读取的配置前缀却不是自己的 比如springcloud-gateway
这个时候我们是无法通过加@RefreshScope注解的方式来实现自动刷新的。这个时候怎么办呢? 别着急,我们可以去使用Apollo中更底层的办法去实现监听和自动刷新。
import com.ctrip.framework.apollo.model.ConfigChangeEvent;
import com.ctrip.framework.apollo.spring.annotation.ApolloConfigChangeListener;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.cloud.context.environment.EnvironmentChangeEvent;
import org.springframework.cloud.gateway.config.GatewayProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
/**
* @Author: lijiawei
* @Date: 2019/1/23 15:55
* @Description: 用于网关属性刷新
*/
@Slf4j
@Component
public class GatewayPropertiesRefresher implements ApplicationContextAware {
private ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
/**
* apollo配置监听器,默认监听的是application命名空间
*
* @param changeEvent
*/
@ApolloConfigChangeListener({"application-routes"})
public void onChange(ConfigChangeEvent changeEvent) {
boolean gatewayPropertiesChanged = false;
for (String changedKey : changeEvent.changedKeys()) {
//前缀为spring.cloud.gateway的key发生了改变(gateway的配置发生了改变)
if (changedKey.startsWith("spring.cloud.gateway.")) {
gatewayPropertiesChanged = true;
break;
}
}
//更新gateway配置
if (gatewayPropertiesChanged) {
refreshGatewayProperties(changeEvent);
}
}
/**
* 更新SpringApplicationContext对象,并更新路由
*
* @param changeEvent
*/
private void refreshGatewayProperties(ConfigChangeEvent changeEvent) {
log.info("Refreshing Gateway properties!");
//更新配置
this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
log.info("Gateway properties refreshed!");
}
}
或者采用下面这种方式
@Component
@Slf4j
public class AppConfig implements ApplicationContextAware {
ApplicationContext applicationContext;
@Autowired
RefreshScope refreshScope;
@ApolloConfigChangeListener(ConfigConsts.NAMESPACE_APPLICATION)
public void onChange(ConfigChangeEvent changeEvent) {
boolean eurekaPropertiesChanged = false;
for (String changedKey : changeEvent.changedKeys()) {
if (changedKey.startsWith("redis.cache")) {
log.info("===============================================================");
log.info("changedKey:{} value:{}",changedKey,changeEvent.getChange(changedKey));
ConfigChange configChange = changeEvent.getChange(changedKey);
configChange.getOldValue();
eurekaPropertiesChanged = true;
break;
}
}
refreshProperties(changeEvent);
if (eurekaPropertiesChanged) {
refreshProperties(changeEvent);
}
}
public void refreshProperties(ConfigChangeEvent changeEvent){
this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
refreshScope.refreshAll();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
就像这样。之后我们再去更改配置就能自动刷新了
如果想了解更多的以及原理可以直接查看下官方文档:https://github.com/ctripcorp/apollo/wiki/Java%E5%AE%A2%E6%88%B7%E7%AB%AF%E4%BD%BF%E7%94%A8%E6%8C%87%E5%8D%97
以上就是这次的全部内容,希望能够帮助到你