架構說設計到數據量較大的應用要從k8s中遷出單獨機器部署
于是將8節點的服務準備遷出,且端口號在數據庫中保存
在不引入springcloud的方式下 啟動spring容器中對args進行配置屬性注入
思路一 通過spring容器獲取信息
public static void main(String[] args) throws IllegalAccessException, NoSuchFieldException {
//WebApplicationType.NONE 獲取bean信息
SpringApplication build = new SpringApplicationBuilder(Application.class).web(WebApplicationType.NONE).build(args);
ConfigurableApplicationContext run = build.run();
ConfigurableEnvironment environment = run.getEnvironment();
//模擬獲取到的端口號
AA bean = run.getBean(AA.class);
int port = bena.port();
//關閉spring 不然會提示重復導致啟動失敗
run.close();
List<String> argList;
if (args != null) {
argList = new ArrayList<>(Arrays.asList(args));
} else {
argList = new ArrayList<>();
}
argList.add("--Dserver.port=6999");
//起作用的行--
argList.add("--server.port=6998");
argList.add("-Dserver.port=6997");
argList.add("-server.port=6996");
argList.add("Dserver.port=6995");
argList.add("server.port=6994");
System.out.println("-------------------------------------------------------------------------");
SpringApplication.run(Application.class, argList.toArray(new String[0]));
}
思路二 非spring容器獲取
public static void main(String[] args) {
//通過靜態方法,jdbc連接方式獲取 配置信息然后寫入args實現動態配置
SpringApplication.run(Application.class,args);
}
額外的知識點
修改final屬性的字段值
MutablePropertySources propertySources = environment.getPropertySources();
for (PropertySource<?> propertySource : propertySources) {
Object source = propertySource.getSource();
if (source instanceof Map) {
//source 是一個只讀map
Object o = Map.class.cast(source).get("server.port");
if (o == null) {
continue;
}
if (o instanceof OriginTrackedValue) {
OriginTrackedValue cast = OriginTrackedValue.class.cast(o);
Field value = OriginTrackedValue.class.getDeclaredField("value");
//value字段 是final 修飾的
//需要去掉modifiers中的Final
Field modifiers = Field.class.getDeclaredField("modifiers");
modifiers.setAccessible(true);
modifiers.setInt(value, modifiers.getModifiers() & ~Modifier.FINAL);
value.setAccessible(true);
value.set(cast, bean.port());
}
}
}