welcome to xlongwei.com

欢迎大家一起学习、交流、分享


QQ:9167702333 邮箱:admin@xlongwei.com

@RefreshScope的使用经历


分类 Java   关键字 分享   标签 java   发布 hongwei  1616492609368
注意 转载须保留原文链接,译文链接,作者译者等信息。  

最近项目中较多地方使用了类似Util.staticUrl的静态地址字段,需要改造为从配置中心或数据库获取值,因此用到了@RerefreshScope注解。

  1. 从配置中心取值
    @Data
    @Slf4j
    @Component
    @RefreshScope
    @Scope("prototype")
    public class InterfaceConfig implements InitializingBean {
         @Value("${platform.hx.url}")
         private String hxUrl;
  2.     @Override
         public void afterPropertiesSet() throws Exception {
             Util.updateUrl(hxUrl);
         }
         @EventListener
         public void eventListener(EnvironmentChangeEvent event) throws Exception {
             log.info("config change keys: {}", event.getKeys());
         }
    }
    @RefreshScope正确的使用方式是在代码中注入InterfaceConfig实例,每次通过getHxUrl()取值。但是项目中较多地方使用了Util.hxUrl,因此需要在nacos配置更新时同步此值。由于项目中没有注入InterfaceConfig实例,也没有调用其getHxUrl方法,因此使用@EventListener监听nacos配置更新,但是此时hxUrl还没有拿到更新后的值,因此不能直接调用Util.updateUrl。@Scope(“prototype”)配合监听事件,会导致InterfaceConfig重新初始化,从而再次调用afterPropertiesSet更新配置。

  3. 从数据库取值
    @Slf4j
    @Component
    public class ApplicationConfig implements  ApplicationListener<ApplicationReadyEvent> {
         @Autowired IBaseClient iBaseClient;
         @Autowired InterfaceConfig interfaceConfig;
         @Override
         public void onApplicationEvent(ApplicationReadyEvent event) {
             interfaceConfig.getHxUrl(); //强制InterfaceConfig初始化一次,以便从nacos获取配置并生效
             Map<String, String> map = iBaseClient.getBaseInfoMap("type");
             String hxUrl = map.get("hxUrl");
             Util.updateUrl(hxUrl);
         }
    }
    ApplicationListener<ApplicationReadyEvent> 在应用启动完成时执行,尝试从数据库获取配置,无对应配置时不更改地址。

    public static void updateUrl(String hxUrl) {
         if(StringUtil.isBlank(hxUrl)) {
             log.info("hx.url is blank, keep old url: {}", Util.HX_Url);
         }else if(Objects.equal(hxUrl, StatusInfoUtil.HX_Url)) {
             log.info("hx.url not change, keep old url: {}", StatusInfoUtil.HX_REQ_Url);
         }else {
             log.info("update hx.url from:{} to:{}", Util.HX_Url, hxUrl);
             StatusInfoUtil.HX_Url = hxUrl;
         }
    }

  4. 手动更新配置
    @ApiOperation(value = "更新服务地址" ,httpMethod = "GET")
    @GetMapping(value = "/web/updateInterfaceConfig", produces = "application/json;charset=UTF-8")
    public ResponseResult<JSONObject> updateInterfaceConfig(String hxUrl){
         JSONObject json = new JSONObject();
         json.put("hxUrlOld", Util.HX_Url);
         if(StringUtils.isAllBlank(hxUrl, lpUrl)) {
             Map<String, String> map = iBaseClient.getBaseInfoMap("type");
             hxUrl = map.get("hxUrl");
         }
         Util.updateUrl(hxUrl);
         json.put("hxUrl", Util.HX_Url);
         return json;
    }
    有时需要更灵活地变更配置,curl提供hxUrl值时可以立即生效,不提供值时可以再次从数据库取值。