apollo配置动态生效

apollo作为应用配置管理中心框架,可以将应用中的配置信息集中管理,且在apollo中修改配置值之后应用中可以动态更新。

动态刷新的原理:应用中配置了apollo后,在spring容器启动过程中,apollo将属性中含有@Value注解与${}的bean注册到apollo框架定义的注册表中。然后通过http长轮询不停地去获取apollo服务端的配置信息,一旦配置发生变化,apollo会根据配置的key找到注册的bean,然后修改bean的属性,从而实现了配置动态生效。

配置值动态刷新的情况有下面几种:1 通过@Value注解读取配置值;2 通过@ConfigurationProperties注解读取配置。

(一) @Value 可以添加在method(比如setxxx())、field(属性)、parameter。apollo中的配置修改后,应用中会动态刷新。

1)读取简单类型:java基本类型、string等。@Value("${xxx:defaultvalue}")

2)读取list、map、set等,或将一定格式的string转为collection:

    /**
     * map配置
     */
    @Value("#{${system.defaultModule}}")
    private Map<String,String> defaultModule;

    /**
     * 简单字符串
     */
    @Value("${system.version: v1.0}")
    private String version;

    /**
     * 将字符串转为集合
     */
    @Value("#{'${system.products}'.split(',')}")
    private List<String> list; // set<string>, string[]均可
    
    @Value("${system.products}")
    private void setProducts(String productStr){
        products = productStr.split(",");
    }

apollo配置如下

system.defaultModule: {"a":"10", "b":"100"}
system.products: aaa,44,678
system.version: v3.0

(二)@ConfigurationProperties 读取配置生成bean。

apollo中的配置修改后,应用中不会动态刷新,需要手动编写程序实现动态刷新。因为spring启动时,已读取配置值且生成了对象。之后再修改配置值后,对象中的属性值并不会改变。

(三)数据库连接配置更改后,对已创建连接不会刷新,只对新生成连接对象生效。

(四)针对bean属性值无法动态刷新的问题,有以下几种方法可以实现动态刷新。

1)基于RefreshScope结合@ApolloConfigChangeListener实现

2)基于EnvironmentChangeEvent结合@ApolloConfigChangeListener实现

3)示例代码如下

properties配置

@ConfigurationProperties(prefix = "wcc.system")
@RefreshScope
@Component("testApolloConfigProperties")
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
@ToString
public class TestApolloConfigProperties {
    private Map<String,String> defaultModule;

    private List<String> products;

    private String version;
}

listener方式一

@Component
public class TestApolloRefreshScopeListener {
    @Autowired
    private RefreshScope refreshScope;

    @ApolloConfigChangeListener(interestedKeyPrefixes = "wcc.system")
    public void refresh() {
        // 指定要刷新的bean
        refreshScope.refresh("testApolloConfigProperties");
    }
}

listener方式二

@Component
public class TestApolloEnvironmentChangeEventListener {
    @Autowired
    private ApplicationContext applicationContext;

    @ApolloConfigChangeListener(interestedKeyPrefixes = "wcc.system")
    public void doRefresh(ConfigChangeEvent changeEvent){
        applicationContext.publishEvent(new EnvironmentChangeEvent(changeEvent.changedKeys()));
    }
}
原文地址:https://www.cnblogs.com/mydesky2012/p/15633350.html