问题:多个
SpringBoot
项目,项目间通过Hessian
调用,每个项目要配置一些一样的配置文件,如数据库连接,Redis相关配置,MQ相关配置。如果一旦需要修改,那么每个配置文件都要修改
解决办法:把共用文件单独放在数据库或者放到一个独立服务中,在项目启动时动态加载配置
具体方案:仿照ConfigFileApplicationListener
写一个配置加载类,并通过spring.factories
指定加载
ConfigFileApplicationListener
public class ConfigFileApplicationListener
implements EnvironmentPostProcessor, SmartApplicationListener, Ordered {
......
}
可见ConfigFileApplicationListener
实现了EnvironmentPostProcessor,Ordered,SmartApplicationListener
三个接口。自定义的配置加载类只需要继承EnvironmentPostProcessor,Ordered
这两个就可以了
自定义的配置加载类
package com.wangyanan.datastructure.common;
import org.json.JSONObject;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.context.config.ConfigFileApplicationListener;
import org.springframework.boot.context.event.ApplicationEnvironmentPreparedEvent;
import org.springframework.boot.context.event.ApplicationPreparedEvent;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.SmartApplicationListener;
import org.springframework.core.Ordered;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MutablePropertySources;
import org.springframework.core.env.PropertiesPropertySource;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.Map;
import java.util.Properties;
/**
* 公共配置文件
*
* @author 王亚楠
* @date 2018年04月23日 18:14
**/
public class MyConfig implements EnvironmentPostProcessor, Ordered {
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
JSONObject jsonObject = new JSONObject();
//此处可以http方式 到配置服务器拉取一堆公共配置+本项目个性配置的json串,拼到Properties里
try {
URL url = new URL("http://wang_ya_nan.gitee.io/common_configuration_file/spring.application");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
//设置请求方式
connection.setRequestMethod("GET");
//连接
connection.connect();
//得到响应码
int responseCode = connection.getResponseCode();
if(responseCode == HttpURLConnection.HTTP_OK){
//得到响应流
InputStream inputStream = connection.getInputStream();
//将响应流转换成字符串
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
StringBuilder stringBuilder = new StringBuilder();
String str;
while ((str = bufferedReader.readLine()) != null) {
stringBuilder.append(str);
}
String json = stringBuilder.toString();
jsonObject = new JSONObject(json);
}
} catch (IOException e) {
e.printStackTrace();
}
Properties properties = new Properties();
Map<String, Object> map = jsonObject.toMap();
map.forEach((key, value) -> properties.setProperty(key, (String) value));
MutablePropertySources propertySources = environment.getPropertySources();
//addLast 结合下面的 getOrder() 保证顺序 读者也可以试试其他姿势的加载顺序
propertySources.addLast(new PropertiesPropertySource("myConfig", properties));
}
/**
* +1 保证application.propertie里的内容能覆盖掉本配置文件中默认的
**/
@Override
public int getOrder() {
return ConfigFileApplicationListener.DEFAULT_ORDER + 1;
}
}
这里是从自己的码云上拉的配置,这里可以自定义实现
如何为每个服务加上配置
- 使用
SpringFactoriesLoader
和spring.factories
SpringFactoriesLoader
属于Spring框架
私有的一种扩展方案,其主要功能就是从指定的配置文件META-INF/spring.factories
加载配置。
我们在
resources
下新建META-INF/spring.factories
,写入:
org.springframework.boot.env.EnvironmentPostProcessor=com.wangyanan.datastructure.common.MyConfig
作用:指定EnvironmentPostProcessor
的实现为我们自定义的类,这时候是对获取项目配置的一种扩展(当前是从远程获取),Ordered接口的作用主要是解决默认配置需要覆盖我们共用配置的问题
具体操作步骤
- 在一个新项目(配置导入项目)中,写好自定义的配置类,加上相关配置文件
- 在需要环境配置的项目中,引入配置倒入项目
网友评论