携手创作,共同生长!这是我参加「日新方案 8 月更文应战」的第18

本篇文章首要叙述以下几个知识点

  • Nacos特点的简略运用
  • 将SpringBoot中的一切装备悉数放入到Nacos中
  • 开发人创立独自的命名空间,修正互不影响
  • Nacos常常变动的装备抽离到外部文件中

将项目中的一切装备悉数放到到

1. 首先引进包

         <!-- nacos 接入-->
           <!-- https://mvnrepository.com/artifact/com.alibaba.boot/nacos-config-spring-boot-starter -->
           <dependency>
               <groupId>com.alibaba.boot</groupId>
               <artifactId>nacos-config-spring-boot-starter</artifactId>
               <version>最新版本号</version>
           </dependency>

2. 装备Nacos的装备文件

  • 主装备; 首要是加载 静态装备 文件的; SpringBoot在发动的时分会先去Nacos中读取装备文件然后加载到Environment中; 静态装备不启用主动改写;
#(下面的装备中只需求吧对应的data-ids、group、data-id 、server-addr、namespace修正为对应数据)#
## -----------------静态文件装备(发动的时分最优先加载 log-enable: true)-------------- ##
nacos:
  config:
    bootstrap:
      log-enable: true # 支撑日志级别的加载机遇(假如需求集成dubbo,请运用此装备加载机遇)
      enable: true # 设置参数nacos.config.bootstrap.enable=true,敞开装备预加载功用
    max-retry: 10 # 主装备 最大重试次数
    auto-refresh: false # 主装备 是否敞开主动改写 (false:不监听特点改变,true:监听特点改变,可是对应的特点注解上也有必要设置autoRefreshed = true才能够实时更新)
    config-retry-time: 3000 # 主装备 重试时刻
    config-long-poll-timeout: 30000 # 主装备 装备监听长轮询超时时刻
    enable-remote-sync-config: false # 主装备 敞开注册监听器预加载装备服务(除非特别事务需求,否则不引荐翻开该参数)
    #答应nacos上的装备优先于本地装备; 意思是:假如nacos装备了某特点,然后在本地的application.yml装备了相同特点;那么会以nacos装备的优先;否则是本地的优先
    remote-first: true
    # 主装备 data-ids  (能够装备多个,假如多个装备文件中有相同的 特点 则优先取最前面的值)
    data-ids: application-static.properties,logback-static.xml
    group: PROJECT_EXAMPLE # 主装备 group-id
    type: yaml # 主装备 装备文件类型
    server-addr: 127.0.0.1:8848
    namespace: # 命名空间
    name: nacos
    password: nacos

上面的静态装备修正最后边的几个特点就行了;

  • 动态装备 动态装备有两种装备 一种是在yml装备文件中装备
nacos:
  config:
    ext-config[0]:
      data-id:  dynamic.properties
      group: PROJECT_EXAMPLE
      #namespace:  # 命名空间 该特点假如为空 或许注释该特点  会承继主特点的命名空间
      # 该特点不承继上面的主装备    是否敞开主动改写 (false:不监听特点改变,true:监听特点改变,可是对应的特点注解上也有必要设置autoRefreshed = true才能够实时更新)
      auto-refresh : true
      type: properties  # 类型 {@link com.alibaba.nacos.api.config.ConfigType}
    ## 假如还想加载其他的装备  copy一下 数组改成1 例如ext-config[1]
    ext-config[1]:
      data-id:  dynamic.yaml
      group: PROJECT_EXAMPLE
      #namespace:  # 命名空间 该特点假如为空 或许注释该特点  会承继主特点的命名空间
      # 该特点不承继上面的主装备    是否敞开主动改写 (false:不监听特点改变,true:监听特点改变,可是对应的特点注解上也有必要设置autoRefreshed = true才能够实时更新)
      auto-refresh: true
      type: yaml  # 类型 {@link com.alibaba.nacos.api.config.ConfigType}

一种用注解的形式@NacosPropertySource 例如上面的动态装备跟下面效果一样

@NacosPropertySource(dataId = "dynamic.properties",groupId = "PROJECT_EXAMPLE",type = ConfigType.PROPERTIES,autoRefreshed = true)
@NacosPropertySource(dataId = "dynamic.yaml",groupId = "PROJECT_EXAMPLE",type = ConfigType.YAML,autoRefreshed = true)

两者的区别: @NacosPropertySource不能够独自指定namespace; 装备文件的方法能够独自指定namespace ; 假如他们都不指定的话,默许承继自 主装备中的namespace装备

3.Nacos的简略运用

3.1 运用@NacosConfigurationProperties将装备绑定到目标中

例子:

/**
 * @author shirenchuang
 * @date 2020/10/20  9:56 上午
 *
 * 将装备中的 list 和listMap 解析并绑定到这个目标中
 * 并能够运用 @Autowired注解运用这个目标
 *
 * nacos中的装备:
 *
 * test.list:
 *     - 1
 *     - 2
 *     - 3
 *     - 4
 * test.listMap:
 *     key-1:
 *         - 1
 *         - 2
 *         - 3
 *         - 4
 *     key-2:
 *         - aa
 *         - dd
 *         - ee
 *         - rr
 *
 *
 */
@NacosConfigurationProperties( prefix = "test1",dataId = "test.yaml",groupId = "PROJECT_EXAMPLE",type = ConfigType.YAML, autoRefreshed = true)
@Configuration
public class Apple {
    private List<String> list;
    private Map<String, List<String>> listMap;
    public List<String> getList() {
        return list;
    }
    public void setList(List<String> list) {
        this.list = list;
    }
    public Map<String, List<String>> getListMap() {
        return listMap;
    }
    public void setListMap(Map<String, List<String>> listMap) {
        this.listMap = listMap;
    }
    @Override
    public String toString() {
        return "Apple{" + "list=" + list + ", listMap=" + listMap + '}';
    }
}

运用的时分就直接用注解@Autowired能够直接运用

    @Autowired
    private Apple apple;

3.2 运用@NacosValue获取特点

    // 是否主动改写特点 有必要在每个特点上都要标示
    @NacosValue(value = "${name:66}",autoRefreshed = true)
    private String name;

假如特点值不存在就取 冒号 后边的默许值;

3.3 也能够运用@Value来获取Nacos装备中的特点值

    @NacosValue(value = "${spring.datasource.url}",autoRefreshed = true)
    private String url;
    @Value(value = "${spring.datasource.url}")
    private String url2;

例如上面的spring.datasource.url的特点是装备在nacos中的;可是上面两个注解都正常打印出来了它的值,为什么呢?@Value是从Spring容器中的Environment中获取对应的特点值,可是在发动Nacos的时分就把数据给加载到了Environment中去了; 所以通过@Value也能获取到特点值; 可是它跟@NacosValue的区别是, 它不能够实时改写数据; 它的值一直都是发动时分第一遍加载的数据 所以咱们也能够用@Value来获取咱们在Nacos中装备的静态数据;作用是一样的 【SpringBoot】装备文件的加载与特点值的绑定

4.将Nacos一部分装备移动到外部文件中

咱们在开发过程中,会常常涉及到装备文件的改动; 还有发布的时分不同环境用不同的装备; 这些装备写在项目的特点文件里面不太稳当; 最好是能够独自拎出来;

例如上面主装备中的 几个特点在不同环境中会常常频频改动;那咱们把他们独自拎出来存放到外部装备文件中;

【SpringBoot】使用Nacos简化SpringBoot配置(所有配置放入到Nacos中)

Spring中读取外部装备文件的方法有许多;可是有一点很重要;便是加载机遇的问题 例如@PropertySource()这个注解根本上是等容器都发动完结的时分才去解析的; 那么咱们发动项目的时分是一开始就加载了Nacos的; 就有必要咱们在加载Nacos的装备文件之前就有必要把Nacos需求的装备数据预备好并加载到 Environment 中去; 相关知识点能够参考: 【Spring Boot 四】发动之预备体系环境environmentPrepared 【SpringBoot】SpringBoot发动流程图和扩展点阐明

那么最终决定咱们能够选择 完成一个 EnvironmentPostProcessor扩展类;

NacosEnvPostProcessor扩展类


import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.logging.DeferredLog;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.springframework.util.StringUtils;
import java.io.IOException;
/**
 * @author shirenchuang
 * @date 2020/7/22  4:58 下午
 *
 * 这个优先级有必要要比 NacosConfigEnvironmentProcessor 的优先级高
 * 不然的话 NacosConfigEnvironmentProcessor 履行的时分 会取不到 Nacos的这几个装备特点
 * 将文件中的特点放到 体系环境变量中; 优先级只会比StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME低
 */
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.logging.DeferredLog;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertySource;
import org.springframework.core.env.StandardEnvironment;
import org.springframework.core.io.DefaultResourceLoader;
import org.springframework.core.io.Resource;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.DefaultPropertySourceFactory;
import org.springframework.core.io.support.EncodedResource;
import org.springframework.core.io.support.PropertySourceFactory;
import org.springframework.util.StringUtils;
import java.io.IOException;
/**
 * @author shirenchuang
 * @date 2020/7/22  4:58 下午
 * 在最初的时分将 外部装备文件特点加载到容器中
 *
 * 这个优先级有必要要比 NacosConfigEnvironmentProcessor 的优先级高
 * 不然的话 NacosConfigEnvironmentProcessor 履行的时分 会取不到 Nacos的这几个装备特点
 * 将文件中的特点放到 体系环境变量中; 优先级只会比StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME低
 */
public class ExternalFilePostProcessor implements EnvironmentPostProcessor, ApplicationListener<ApplicationEvent>, Ordered {
    /**
     * 这个时分Log体系还没有初始化  运用DeferredLog来记录  并在onApplicationEvent进行回放
     * */
    private static final DeferredLog LOGGER = new DeferredLog();
    private  ResourceLoader resourceLoader = new DefaultResourceLoader();
    @Override
    public int getOrder() {
        return 0;
    }
    /**
     * 将文件中的nacos装备文件 加载到 environment中;
     * 便利Nacos能够拿到 静态装备
     *
     * @param environment
     * @param application
     */
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        String filePath = environment.getProperty("nacos_file_path");
        if(StringUtils.isEmpty(filePath)){
            LOGGER.info("\n [----未装备外部特点路径-----] \n");
            return;
        }
        String resolvedLocation = environment.resolveRequiredPlaceholders(filePath);
        resolvedLocation = "file:"+resolvedLocation;
        PropertySourceFactory factory = new DefaultPropertySourceFactory();
        Resource resource = this.resourceLoader.getResource(resolvedLocation);
        try {
            addPropertySource(factory.createPropertySource(filePath, new EncodedResource(resource)),environment);
        } catch (IOException e) {
            LOGGER.error(" 外部装备路径 - Properties location [" + filePath + "] not resolvable: " + e.getMessage());
        }
    }
    private void addPropertySource(PropertySource<?> propertySource,ConfigurableEnvironment environment) {
        MutablePropertySources propertySources = environment.getPropertySources();
        //添加到 systemEnvironment  优先级只比 体系特点 和命令行特点等等的低
        propertySources.addAfter(StandardEnvironment.SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, propertySource);
    }
    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        LOGGER.replayTo(ExternalFilePostProcessor.class);
    }
}

然后装备一下spring.factories;

org.springframework.boot.env.EnvironmentPostProcessor=com.daimler.example.service.common.NacosEnvPostProcessor

【SpringBoot】使用Nacos简化SpringBoot配置(所有配置放入到Nacos中)

相关知识点 【SpringBoot 二】spring.factories加载机遇剖析

然后本地创立一个文件

【SpringBoot】使用Nacos简化SpringBoot配置(所有配置放入到Nacos中)

在yml中装备文件路径

#nacos 的根本装备(放在服务器本地文件上, 包含  nacos.config.server-addr、 nacos.config.namespace、 username、password)
nacos_file_path: /**/**/nacos_static/project_example-nacos.properties

Spring中完成上面的功用没有那么杂乱


@EnableNacosConfig(globalProperties = @NacosProperties(username = "${nacos.config.username}", password = "${nacos.config.password}",
    serverAddr = "${nacos.config.server-addr}",namespace = "${nacos.config.namespace}"   ))
@NacosPropertySource(dataId = "dynamic.yaml",groupId = "PROJECT_EXAMPLE",type = ConfigType.YAML,autoRefreshed = true)
public class NacosConfig {
}
@Configuration
@PropertySource(value = "file:/etc/nacos.properties")
@ComponentScan(basePackages = "com.xx")
@Import( value = {NacosConfig.class})
public class SpringConfig {
}

然后外部装备文件装备

【SpringBoot】使用Nacos简化SpringBoot配置(所有配置放入到Nacos中)

5.每个开发人员一套自己的装备

在本地开发过程中,咱们可能会常常修正装备文件;但可能改了之后会影响到别人;就有这样的需求;我改装备的时分 只影响我自己;

咱们能够看到上面的装备中 有一个装备 nacos.config.namespace= ; 这个是命名空间;通过这样一个特点咱们能够运用不同的装备;

具体用法

  • 新建一个归于自己的命名空间
    【SpringBoot】使用Nacos简化SpringBoot配置(所有配置放入到Nacos中)
  • 将需求克隆的装备 从指定空间克隆到自己刚刚创立的空间
    【SpringBoot】使用Nacos简化SpringBoot配置(所有配置放入到Nacos中)
  • 将自己本地nacos特点装备的namespace 改成自己刚刚创立的命名空间id(留意是 ID)
  • 重新发动,搞定!

完整的yml装备


#nacos 的根本装备(放在服务器本地文件上, 包含  nacos.config.server-addr、 nacos.config.namespace、 username、password)
nacos_file_path: /**/**/nacos_static/project_example-nacos.properties
#(下面的装备中只需求吧对应的data-ids、group、data-id 修正为对应数据)#
## -----------------静态文件装备(发动的时分最优先加载 log-enable: true)-------------- ##
nacos:
  config:
    bootstrap:
      log-enable: true # 支撑日志级别的加载机遇(假如需求集成dubbo,请运用此装备加载机遇)
      enable: true # 设置参数nacos.config.bootstrap.enable=true,敞开装备预加载功用
    max-retry: 10 # 主装备 最大重试次数
    auto-refresh: false # 主装备 是否敞开主动改写 (false:不监听特点改变,true:监听特点改变,可是对应的特点注解上也有必要设置autoRefreshed = true才能够实时更新)
    config-retry-time: 3000 # 主装备 重试时刻
    config-long-poll-timeout: 30000 # 主装备 装备监听长轮询超时时刻
    enable-remote-sync-config: false # 主装备 敞开注册监听器预加载装备服务(除非特别事务需求,否则不引荐翻开该参数)
    #答应nacos上的装备优先于本地装备; 意思是:假如nacos装备了某特点,然后在本地的application.yml装备了相同特点;那么会以nacos装备的优先;否则是本地的优先
    remote-first: true
    # 主装备 data-ids  (能够装备多个,假如多个装备文件中有相同的 特点 则优先取最前面的值)
    data-ids: 静态装备1,静态装备2,logback.xml
    group: 自己的group # 主装备 group-id
    type: yaml # 主装备 装备文件类型
    ## ---------------假如 运用装备方法便是下面的; 假如用@NacosPropertySource注解方法就删掉下面的 ---------------------------  ##
    ext-config[0]:
      data-id:  自己的data-id
      group: 自己的group
      #namespace:  # 命名空间 该特点假如为空 或许注释该特点  会承继主特点的命名空间
      # 该特点不承继上面的主装备    是否敞开主动改写 (false:不监听特点改变,true:监听特点改变,可是对应的特点注解上也有必要设置autoRefreshed = true才能够实时更新)
      auto-refresh : true
      type: properties  # 类型 {@link com.alibaba.nacos.api.config.ConfigType}
    ## 假如还想加载其他的装备  copy一下 数组改成1 例如ext-config[1]
    ext-config[1]:
      data-id:  自己的data-id
      group: 自己的group
      #namespace:  # 命名空间 该特点假如为空 或许注释该特点  会承继主特点的命名空间
      # 该特点不承继上面的主装备    是否敞开主动改写 (false:不监听特点改变,true:监听特点改变,可是对应的特点注解上也有必要设置autoRefreshed = true才能够实时更新)
      auto-refresh: true
      type: yaml  # 类型 {@link com.alibaba.nacos.api.config.ConfigType}

外部装备文件 /**/**/nacos_static/project_example-nacos.properties

  # 主装备服务器地址
   nacos.config.server-addr=127.0.0.1:8848
   nacos.config.username=nacos
   nacos.config.password=nacos
   # 命名空间 (空为默许的public)
   nacos.config.namespace=