springboot通过远程加载配置文件

方式一

package com.ddemo;

import cn.hutool.core.io.FileUtil;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ByteArrayResource;

import java.io.IOException;
import java.util.List;

// 这种方式要在 resources/META-INF/spring.factories里加上org.springframework.boot.env.EnvironmentPostProcessor=com.ddemo.LoadConfig
public class LoadConfig implements EnvironmentPostProcessor, Ordered {
    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
        try {
            PropertySource ss = getSource();
            environment.getPropertySources().addFirst(ss);
            System.out.println("加载配置完成");
        } catch (Exception e) {
            throw new RuntimeException("Failed to load remote YML config", e);
        }
    }

    @Override
    public int getOrder() {
        return Ordered.HIGHEST_PRECEDENCE + 10; // 确保比其他配置源先加载
    }

    private PropertySource getSource() throws IOException {
        // 1. 从远程获取YML配置
        String yamlContent = FileUtil.readUtf8String("f://application.yml");
        System.out.println("加载成功1111111");
        // 2. 转换为PropertySource
        YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
        List<PropertySource<?>> sources = loader.load("LoadConfig",
                new ByteArrayResource(yamlContent.getBytes()));
        return sources.get(0);
    }
}

方式二

package com.ddemo;

import cn.hutool.core.io.FileUtil;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ByteArrayResource;

import java.io.IOException;
import java.util.List;

public class RemoteYmlApplicationRunListener implements ApplicationListener {

    @Override
    public void onApplicationEvent(ApplicationEvent event) {
        ConfigurableEnvironment env = ((ApplicationEnvironmentPreparedEvent)event).getEnvironment();
        try {
            PropertySource ss=  getSource();
            env.getPropertySources().addFirst(ss);
        } catch (IOException e) {
            throw new RuntimeException("Failed to load remote YML config", e);
        }
    }

    private PropertySource getSource() throws IOException {
        // 1. 从远程获取YML配置
        String yamlContent = FileUtil.readUtf8String("f://application.yml");
        System.out.println("加载成功1111111");
        // 2. 转换为PropertySource
        YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
        List<PropertySource<?>> sources = loader.load("LoadConfig",
                new ByteArrayResource(yamlContent.getBytes()));
        return sources.get(0);
    }
}

方式三


package com.xf.config;


import cn.hutool.core.io.FileUtil;
import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONUtil;
import cn.hutool.setting.dialect.Props;
import com.google.common.collect.ImmutableMap;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.env.YamlPropertySourceLoader;
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.MapPropertySource;
import org.springframework.core.env.PropertySource;
import org.springframework.core.io.ByteArrayResource;

import java.io.IOException;
import java.util.Date;
import java.util.List;

@Slf4j
public class RemoteYmlInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {

String conffile = "/etc/tl.conf";

@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
// 先从环境变量加载
String url = applicationContext.getEnvironment().getProperty("saasmanageapi");
String token = applicationContext.getEnvironment().getProperty("managetoken");
if (StrUtil.isBlank(url)) {
log.info("无环境变量,尝试系统配置加载");
if (!FileUtil.exist(conffile)) {
log.info("无配置文件,直接取默认");
return;
}
Props props = new Props(conffile);
url = props.getStr("saasmanageapi");
token = props.getStr("managetoken");

//这个地方把saasmanageapi 加载到spring 容器里面
MapPropertySource propertySource = new MapPropertySource("myCustomProps", ImmutableMap.of("saasmanageapi", url));
applicationContext.getEnvironment()
.getPropertySources()
.addAfter("commandLineArgs", propertySource);
// .addFirst(propertySource);
}
if (StrUtil.isBlank(url) || StrUtil.isBlank(token)) {
log.info("无配置文件,直接取默认");
return;
}
//log.info("环境变量:{},{}",url,token);
String application = applicationContext.getEnvironment().getProperty("spring.application.name");
try {
PropertySource ss= getSource();
MutablePropertySources propertySources = applicationContext.getEnvironment().getPropertySources();
// 检查命令行参数是否存在
if (propertySources.contains("commandLineArgs")) {
propertySources.addAfter("commandLineArgs", ss);
} else {
// 如果不存在,添加到最前面
propertySources.addFirst(ss);
}
} catch (Exception e) {
throw new RuntimeException("Failed to load remote YML config", e);
}

}

private PropertySource getSource(String baseUrl, String application, String token) throws IOException {
// 1. 从远程获取YML配置
String ts = new Date().getTime() + "";
String result = HttpRequest.post(baseUrl + "/applicationConfig/getConfig")
.header("Content-Type", "application/json")
.header("ts", ts)
.header("sign", SecureUtil.md5(ts + token))
.body(JSONUtil.toJsonStr(Dict.create().set("appname", application)))
.timeout(20000).execute().body();

log.info("接口请求地址:" + baseUrl);
String yamlContent = JSONUtil.parseObj(result).getJSONObject("data").getStr("content");
if (StrUtil.isBlank(yamlContent))
return null;
// 2. 转换为PropertySource
YamlPropertySourceLoader loader = new YamlPropertySourceLoader();
List<PropertySource<?>> sources = loader.load("LoadConfig", new ByteArrayResource(yamlContent.getBytes()));
return sources.get(0);
}
}

 

注后两种要在启动时注册:

    public static void main(String[] args){
//        ApplicationContext context = SpringApplication.run(App.class, args);
        new SpringApplicationBuilder(App.class)
//                .initializers(new RemoteYmlInitializer())
                .listeners(new RemoteYmlApplicationRunListener()).run(args);
    }

 

posted @ 2025-06-18 19:11  wujf  阅读(24)  评论(0)    收藏  举报