spring cloud 本地配置研究
发布日期:2021-06-28 19:59:42 浏览次数:2 分类:技术文章

本文共 2801 字,大约阅读时间需要 9 分钟。

已知: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
,,,,,,
可以尝试加入
s
pring.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!配置文件加载完毕”

转载地址:https://blog.csdn.net/xxxxssss12/article/details/80967807 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:HashMap阅读(jdk1.8)
下一篇:ServerSocketChannel+Selector实现多路复用io

发表评论

最新留言

路过,博主的博客真漂亮。。
[***.116.15.85]2024年04月19日 14时29分46秒