spring cloud 本地配置研究

本文探讨了如何优化 Spring Cloud 应用中的配置管理,通过将 bootstrap 分离并自定义加载公共配置,解决了本地配置繁琐的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

已知:spring cloud先加载bootstrap,后加载远程config-server的application。
对于一个服务,需要公共配置:
  1. 注册中心地址;
  2. 日志级别
  3. configServer的server-id,profile,label
另外需要私有配置:
  1. spring.application.name服务名
  2. server.port端口名
  3. 需要在application拉取的配置名。
问题:目前所有服务都需要一个bootstrap.yml,并且不能公用。怎么才能简化本地配置?
解决方案:
  1. 想办法将bootstrap一分为二,加载一个服务器上共有的配置,并加载一个私有配置(或者直接以环境变量形式写在启动脚本中。)
  2. 在main方法之前,自己加载这两个配置,并存储到环境变量中。
  3. 自己加载公共配置文件,私有配置放入环境变量;并将自己加载的配置文件注入springboot

考虑方法1,先看源码。
入口:SpringApplication.run(String... args)
,,,,,,
另一个切入点:ConfigFileApplicationListener.onApplicationEvent
,,,,,,
可以尝试加入spring.config.location环境变量来指定加载配置文件。

考虑到执行SpringApplication.run方法之前可能还需要做其他事情。所以这个干脆也放在run方法外面了。采用方法2。
执行方法2时发现一个问题。可能springboot并不会从系统环境变量中读取相应配置,并且将所有服务配置都放到环境变量中,有点污染环境变量的感觉。于是想到方法3

读取源码发现,spring有一个ConfigurableEnvironment,其中有一个propertySources属性,维护了一个配置list。关键在于想办法把配置加载到这个list中
本地配置文件-bootstrap.yml加载时间点为:ConfigFileApplicationListener.onApplicationEvent。在spring触发这个事件的时候会加载相应配置文件。

代码如下。
@Override
public void onApplicationEvent(ApplicationEvent event) {
   if (event instanceof ApplicationEnvironmentPreparedEvent) {
      onApplicationEnvironmentPreparedEvent(
            (ApplicationEnvironmentPreparedEvent) event);
   }
   if (event instanceof ApplicationPreparedEvent) {
      onApplicationPreparedEvent(event);
   }
}
在onApplicationEnvironmentPreparedEvent方法中,调用了postProcessor.postProcessEnvironment(event.getEnvironment(),
                    event.getSpringApplication());方法。
两个方案:1. 自己写一个listener,监听onApplicationEvent。2.实现EnvironmentPostProcessor接口,等着spring调用
使用方案2。
定义:public class CommonConfig implements EnvironmentPostProcessor
初始化配置方法:
private static Properties prop = new Properties();
public static void init(String[] args) {
    String filePathStr = sysProp.getProperty(sysProp_filePath, defaultConfigFilePath);
    if (!StringUtils.isEmpty(filePathStr)) {
        // 加载配置文件
       String[] filePaths = filePathStr.split(";");
        for (String filePath : filePaths) {
            Properties properties = resolveFileAddProp(filePath, prop);
            prop.putAll(properties);
        }
    }
}
实现接口方法:
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
    try {
        init(null);
        PropertiesPropertySource propertiesPropertySource = new PropertiesPropertySource("blogCommon", prop);
        environment.getPropertySources().addLast(propertiesPropertySource);
        LOG.info("CommonConfig...postProcessEnvironment end!配置文件加载完毕");
    } catch (Exception e) {
        e.printStackTrace();
    }
}
然后在META-INF/spring.factories中添加:
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor,\
com.xs.blog.env.CommonConfig

大功告成。启动之后会出现这一行日志。CommonConfig...postProcessEnvironment end!配置文件加载完毕”
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值