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); }