Java 静态(static)方法读取 Nacos 配置中心

为了降成本节省服务器资源,需要将配置中心从 Apollo 切换到 Nacos,因为注册中心是 Nacos 直接复用集群即可。

问题描述

util 里面获取配置的方法都是 static 静态方法,这就导致了 @Value 根本获取不到 Nacos 里面的配置,所有都改成非静态方法改动很大,很不实际,对调用方很不友好。

尝试过程

查了很多关于Nacos 获取配置中心的资料,资料都很浅显,都是在一个 controller 里面获取,关于静态方法获取的资料找到篇是用 @PostConstruct 注解一个方法将变量赋值给一个 static 变量,这种方法还真行,不过缺点很明显,参数只会在进程启动的时候加载进去,配置中心修改之后并不会生效,需要重启进程才会生效,没有什么价值。

解决方案

试了很多方案都行不通,于是请教组内老司机帮忙协助,在静态方法用 SpringBeanUtil.getBean(AppConfig.class) 这个方法先实例化 bean,然后用 bean 去调用里面的动态方法,是的,获取配置里面的方法还是换成了动态的,这样才方便获取到 @Value 的值,但是用来给业务层调用的方法依然是 static,对业务层调用无影响。

Nacos 配置中心接入流程梳理

官方文档:https://nacos.io/zh-cn/docs/quick-start-spring-cloud.html

1.pom.xml 增加 dependency

<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>

2.增加配置文件

resources/bootstrap.properties

3.写一个动态方法用来获取配置

package com.yeelight.cupnoodles.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Component;

/**
 * Configure
 *
 * @author Scott Yu
 * @date 2020/3/17 2:29 PM
 */
@RefreshScope
@Component
public class AppConfig {

    @Value("${corporation_keys:}")
    public String corporationKeys;

    /**
     * Get all corporation keys
     * 
     * @author Scott Yu
     * @date 2020/3/18 4:29 PM
     */
    public JSONObject getCorporationKeys() {
        return JSON.parseObject(corporationKeys);
    }
}

4.在 static 方法里面使用 SpringBeanUtil.getBean 调用

package com.yeelight.cupnoodles.utils;

import com.alibaba.fastjson.JSONObject;
import com.yeelight.service.framework.util.SpringBeanUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * Get corporation configure
 *
 * @author Scott Yu
 * @date 2020/3/18 9:57 AM
 */
@Slf4j
@Component
public class Corporation {

    public static String getCorporationName(String key) {
        String name = "";

        try {
            AppConfig configBean = SpringBeanUtil.getBean(AppConfig.class);
            JSONObject corporationKeys = configBean.getCorporationKeys();
            name = corporationKeys.getJSONObject(key).getString("name");
        } catch (NullPointerException e) {

        } catch (Exception e) {
            log.error("getCorporationName exception", e);
        }

        return name;
    }
}

总结

从 Apollo 换到 Nacos 感觉是一种架构降级,Nacos 做配置中心很多地方没有 Apollo 做的好用,文档里面的 demo 也没有 Apollo 的完善,Nacos 的配置中心感觉就是本地配置文件的一个 web 版,没有像 Apollo 那样独立出 key 的概念。

评论