描述
- spring boot项目中我们通常通过以下配置在开发/测试/生成指定不同的配置文件读取不同的配置值。
## 在application.properties中使用
spring.profiles.active=dev
## 在application.yml中使用
spring:
profiles:
active: dev
- 当有的时候,一些公共模块的工具类也需要更具不同的环境读取不同的值。比如文件上传工具类,显然在不同的环境中上传路径是不同的。公共模块不能像spring boot直接通过
spring.profiles.active=dev
指定配置文件。这时我们会在使用到上传工具类的地方的application.properties均添加上传路径的配置值。 - 如果修改的话需要修改多处地方,先不说容不容易出错。就是想能不能在一个地方配置之后各个微服务中都能够使用。像常量那样使用。
我的思路
- 于是我想到了,一般微服务会有一个公共的模块,存放一个工具类或实体类的核心包。但是这个模块通常不是一个spring boot项目,并不能读取application.properties。
- 通常我们把公共模块的包打包到各个微服务,可以通过@PropertySource可以读取到spring.profiles.active的值,于是这就好办了。
- @PropertySource(value = “classpath:config/config-${spring.profiles.active}.properties”)
第一步:
|--src/
|--config/
|-- config-dev.properties
|-- config-test.properties
|-- config-line.properties
# 通过服务器上传文件时,服务端创建临时文件的位置
TEMP_FILE_DIR = E:\\TEMP\\
# 通过服务器上传文件时,服务端创建临时文件的位置
TEMP_FILE_DIR = /temp-test/
# 通过服务器上传文件时,服务端创建临时文件的位置
TEMP_FILE_DIR = /temp-line/
第二步:
- 通过@Value("${TEMP_FILE_DIR}")读取配置文件
- 注意 @PostConstruct 修饰的方法,对象被注入后执行。
@Data
@Component
@PropertySource(value = "classpath:config/config-${spring.profiles.active}.properties")
public class ConfigProperties {
@Value("${ALI_ACCESSKEY_ID}")
public String ALI_ACCESSKEY_ID;
@Value("${ALI_ACCESSKEY_SECRET}")
public String ALI_ACCESSKEY_SECRET;
@Value("${ALI_OSS_MAX_SIZE}")
public int ALI_OSS_MAX_SIZE;
@Value("${ALI_OSS_EXPIRE}")
public int ALI_OSS_EXPIRE;
@Value("${ALI_OSS_DIR_PREFIX}")
public String ALI_OSS_DIR_PREFIX;
@Value("${ALI_OSS_ENDPOINT}")
public String ALI_OSS_ENDPOINT;
@Value("${ALI_OSS_BUCKET_NAME}")
public String ALI_OSS_BUCKET_NAME;
@Value("${ALI_OSS_CALLBACK}")
public String ALI_OSS_CALLBACK;
@Value("${TEMP_FILE_DIR}")
public String TEMP_FILE_DIR;
@Value("${REQUEST_PROTOCOL}")
public String REQUEST_PROTOCOL;
@Value("ALI_OSS_FILE_READ_URL")
public String ALI_OSS_FILE_READ_URL;
@Value("${ALI_PAY_NOTIFY_URL}")
public String ALI_PAY_NOTIFY_URL;
@Value("${ALI_PAY_TIME_TYPE}")
public String ALI_PAY_TIME_TYPE;
@Value("${ALI_PAY_URL}")
public String ALI_PAY_URL;
@Value("${WECHAT_PAY_NOTIFY_URL}")
public String WECHAT_PAY_NOTIFY_URL;
@PostConstruct
public void init(){
try {
new Constants().setConfigInfo(this);
}catch (Exception e){
System.out.println("初始化失败");
}
}
}
- 但是这样并不能像常量一样使用,需要在使用的地方@Autowired注入。通过上面的
init()
把对象的值赋给常量类
public class Constants {
public static String ALI_ACCESSKEY_ID;
public static String ALI_ACCESSKEY_SECRET;
public static int ALI_OSS_MAX_SIZE;
public static int ALI_OSS_EXPIRE;
public static String ALI_OSS_DIR_PREFIX;
public static String ALI_OSS_ENDPOINT;
public static String ALI_OSS_BUCKET_NAME;
public static String ALI_OSS_CALLBACK;
public static String TEMP_FILE_DIR;
public static String REQUEST_PROTOCOL;
public static String ALI_OSS_FILE_READ_URL;
public static String ALI_PAY_NOTIFY_URL;
public static String ALI_PAY_TIME_TYPE;
public static String ALI_PAY_URL;
public static String WECHAT_PAY_NOTIFY_URL;
public void setConfigInfo(ConfigProperties config) throws Exception{
Field[] configFields = config.getClass().getDeclaredFields();
Field[] constantsFields = Constants.class.getDeclaredFields();
for (Field confField : configFields){
for (Field consFiled: constantsFields){
if(confField.getName().equals(consFiled.getName())){
consFiled.set(this,confField.get(config));
break;
}
}
continue;
}
}
}
- 需要注意的是:Constants类和ConfigProperties类字段名相同的才会对应取到值。
使用
- 不仅可以区分开发/测试/正式环境,还可以在各个项目中使用到配置文件的值。需要修改是也仅仅需要修改一个地方。直接像使用常量一样。使用方式如下:
private static OSS createOssClient(){
if(ossClient == null){
ossClient = new OSSClientBuilder().build(Constants.ALI_OSS_ENDPOINT, Constants.ALI_ACCESSKEY_ID, Constants.ALI_ACCESSKEY_SECRET);
}
return ossClient;
}
最后
- 如果在这里获得过启发和思考,希望点赞支持!对于内容有不同的看法欢迎来信交流。
- 技术栈 >> java
- 邮箱 >> 15673219519@163.com