apollo動態(tài)刷新ConfigurationProperties注解標(biāo)注的配置類方式
apollo動態(tài)刷新ConfigurationProperties注解標(biāo)注的配置類
默認(rèn)情況下 apollo無法刷新 ConfigurationProperties標(biāo)注的屬性實時更新
我查看官方文檔他推薦了兩種實現(xiàn)思路
@RefrashScope和通過EnvironmentChangeEvent
這兩個都是在spring-cloud-context中提供的
我簡單舉個例子
/**
* @Description
* @Author changyandong
* @Emoji (゜ - ゜)つ干杯
* @Created Date: 2019/11/20 9:01
* @ClassName MsGatewayProperties
* @Version: 1.0
*/
@Component
@ConfigurationProperties("ms.gateway")
public class MsGatewayProperties {
private MsGatewayUrlProperties url = new MsGatewayUrlProperties();
public MsGatewayUrlProperties getUrl() {
return url;
}
public void setUrl(MsGatewayUrlProperties url) {
this.url = url;
}
}
/**
* @Description
* @Author changyandong
* @Emoji (゜ - ゜)つ干杯
* @Created Date: 2019/11/20 9:02
* @ClassName MsGatewayUrlProperties
* @Version: 1.0
*/
public class MsGatewayUrlProperties {
private String sss;
private String xxx;
public String getSss() {
return sss;
}
public void setSss(String sss) {
this.sss = sss;
}
public String getXxx() {
return xxx;
}
public void setXxx(String xxx) {
this.xxx = xxx;
}
}
然后我創(chuàng)建一個apollo監(jiān)聽類 這里的ConfigChangeService是我們框架封裝的
如果自己寫的話一個普通的@ApolloConfigChangeListener類即可
/**
* @Description
* @Author changyandong
* @Emoji (゜ - ゜)つ干杯
* @Created Date: 2019/11/20 9:00
* @ClassName MsGatewayAppolloChangeSerivce
* @Version: 1.0
*/
@Component
public class MsGatewayApolloChangeService implements ConfigChangeService, ApplicationContextAware {
private Logger logger = LoggerFactory.getLogger(MsGatewayApolloChangeService.class);
private ApplicationContext applicationContext;
@Override
public void detectConfigChanges(ConfigChangeEvent changeEvent) {
boolean gatewayPropertiesChanged = false;
for (String changedKey : changeEvent.changedKeys()) {
//前綴為spring.cloud.gateway的key發(fā)生了改變(gateway的配置發(fā)生了改變)
if (changedKey.startsWith("ms.gateway")) {
gatewayPropertiesChanged = true;
break;
}
}
//更新gateway配置
if (gatewayPropertiesChanged) {
refreshGatewayProperties(changeEvent);
}
}
/**
* 更新SpringApplicationContext對象,并更新路由
*
* @param changeEvent
*/
private void refreshGatewayProperties(ConfigChangeEvent changeEvent) {
//更新配置
this.applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
}
@Override
public int getOrder() {
return 1;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}
}
這時他給spring推了一個事件 EnvironmentChangeEvent
這時會觸發(fā)ConfigurationPropertiesRebinder的onApplicationEvent方法進(jìn)而觸發(fā)rebind方法
@Component
@ManagedResource
public class ConfigurationPropertiesRebinder
implements ApplicationContextAware, ApplicationListener<EnvironmentChangeEvent> {
private ConfigurationPropertiesBeans beans;
private ApplicationContext applicationContext;
private Map<String, Exception> errors = new ConcurrentHashMap<>();
public ConfigurationPropertiesRebinder(ConfigurationPropertiesBeans beans) {
this.beans = beans;
}
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
this.applicationContext = applicationContext;
}
/**
* A map of bean name to errors when instantiating the bean.
* @return The errors accumulated since the latest destroy.
*/
public Map<String, Exception> getErrors() {
return this.errors;
}
@ManagedOperation
public void rebind() {
this.errors.clear();
// 這里會把標(biāo)注了ConfigurationProperties的所有類都掃一遍
for (String name : this.beans.getBeanNames()) {
rebind(name);
}
}
@ManagedOperation
public boolean rebind(String name) {
if (!this.beans.getBeanNames().contains(name)) {
return false;
}
// 這里他把對象 銷毀再創(chuàng)建 但是由于我只想刷新我自己的類 這里卻把所有帶ConfigurationProperties注解的都銷毀重新創(chuàng)建
// 這樣就很難以讓我們采用這種方式
if (this.applicationContext != null) {
try {
Object bean = this.applicationContext.getBean(name);
if (AopUtils.isAopProxy(bean)) {
bean = ProxyUtils.getTargetObject(bean);
}
if (bean != null) {
this.applicationContext.getAutowireCapableBeanFactory()
.destroyBean(bean);
this.applicationContext.getAutowireCapableBeanFactory()
.initializeBean(bean, name);
return true;
}
}
catch (RuntimeException e) {
this.errors.put(name, e);
throw e;
}
catch (Exception e) {
this.errors.put(name, e);
throw new IllegalStateException("Cannot rebind to " + name, e);
}
}
return false;
}
@ManagedAttribute
public Set<String> getBeanNames() {
return new HashSet<>(this.beans.getBeanNames());
}
@Override
public void onApplicationEvent(EnvironmentChangeEvent event) {
if (this.applicationContext.equals(event.getSource())
// Backwards compatible
|| event.getKeys().equals(event.getSource())) {
rebind();
}
}
}



總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
- apollo更改配置刷新@ConfigurationProperties配置類
- SpringBoot @ConfigurationProperties + Validation實現(xiàn)啟動期校驗解決方案
- 如何讓@EnableConfigurationProperties的值注入到@Value中
- 解讀@ConfigurationProperties和@value的區(qū)別
- springboot使用@ConfigurationProperties實現(xiàn)自動綁定配置參數(shù)屬性
- 解讀@ConfigurationProperties的基本用法
- SpringBoot中的@ConfigurationProperties注解的使用
- SpringBoot中@ConfigurationProperties自動獲取配置參數(shù)的流程步驟
相關(guān)文章
Spring Cloud Zuul路由規(guī)則動態(tài)更新解析
這篇文章主要介紹了Spring Cloud Zuul路由規(guī)則動態(tài)更新解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-11-11
Maven中optional和scope元素的使用弄明白了嗎
這篇文章主要介紹了Maven中optional和scope元素的使用弄明白了嗎,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-12-12
IDEA中WebService生成Java代碼并調(diào)用外部接口實現(xiàn)代碼
這篇文章主要介紹了IDEA中WebService生成Java代碼并調(diào)用外部接口實現(xiàn),本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-05-05
Nacos?版本不一致報錯Request?nacos?server?failed解決
這篇文章主要為大家介紹了Nacos?版本不一致報錯Request?nacos?server?failed的解決方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11

