一、前言
一种场景下是为了降低代码的耦合,需要将一些配置参数放到配置文件中(数据库中也是一个方式),以免以后修改时去代码中一个一个找;另一种场景就是一个项目会有开发环境,测试环境、生产环境等等,每个环境下,(比如连接的数据库的地址不同)或者其他的一些自定义属性不同。
二、获取自己创建的xxx.properties文件中的属性值
<1> task.properties (在resource根目录下的)
queryNumber=200
taskOneCode=bsa
taskTwoCode=bs
taskThreeCode=ba
<2> PropertiesUtil.java
package com.zlc.springcloud.util;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.springframework.stereotype.Component;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
@Component
public class PropertiesUtil {
private static final Logger log = LoggerFactory.getLogger(PropertiesUtil.class);
/**描述: 获取properties配置文件的value
*@param key 键值
*@return : env.getProperty(key) value值
*@Author : 追到乌云的尽头找太阳
*创建时间:2017/9/6
*/
public String getPropertiesValue( String propertiesName , String key){
Configuration propertiesConfig ;
// 获取classpath 路径下的properties文件,如果文件不在跟目录,请在propertiesName 前加上文件名称,可以在此基础上改造
String properties = propertiesName+".properties";
String value ;
//返回properties中的参数
try {
propertiesConfig = new PropertiesConfiguration(properties);
value = propertiesConfig.getString(key);
if (null== propertiesConfig.getString(key) || "".equals(propertiesConfig.getString(key))) {
log.error( "获取 {} 配置文件中key为 {} 的值不存在" ,properties, key );
}else {
return value;
}
} catch (ConfigurationException e) {
log.error("读取配置文件异常,异常信息为:"+ e);
e.printStackTrace();
value = null;
}
return value;
}
/**
* 修改properties文件中属性值对应的值,打成jar包无法修改
* @param propertiesName properties文件名称
* @param key 属性名称
* @param value 属性值
*/
public void updateProperties(String propertiesName, String key, String value){
String basePath = this.getClass().getResource("/").getPath() + propertiesName;
FileReader fr = null;
BufferedReader bf = null;
StringBuilder buf = new StringBuilder();
try {
fr = new FileReader(basePath);
bf = new BufferedReader(fr);
String line = null;
while( (line = bf.readLine()) != null){
String cloneLine = line;
if(line.trim().indexOf("#", 0) == 0){
buf.append(cloneLine);
}else{
String property = cloneLine.trim().split("=")[0];
if(key.equals(property.trim())){
buf.append(property.trim() + " = " + value);
}else{
buf.append(cloneLine);
}
}
buf.append(System.getProperty("line.separator"));
}
} catch (IOException e) {
//文件读取失败
e.printStackTrace();
} finally{
if(bf != null){
try {
bf.close();
} catch (IOException e) {
//带缓冲的字符输入流关闭失败
e.printStackTrace();
}
}
}
FileWriter fw = null;
BufferedWriter bw = null;
try {
fw = new FileWriter(basePath);
bw = new BufferedWriter(fw);
bw.write(buf.toString());
} catch (IOException e) {
//字符输出流类创建失败
e.printStackTrace();
} finally {
if(bw != null){
try {
bw.close();
} catch (IOException e) {
//带缓冲的字符输出流关闭失败
e.printStackTrace();
}
}
}
}
}
<3> 测试例子就不贴了,可以根据自己的想法对上述方法改造。需要注意的是修改方法,打成jar包后是无法修改的(因为打成jar包后,这个文件的路径变了,我已经测试过了,可以不要在踩这个坑了)
三、不同环境获取同一key对应的不同值
就像上面说的,开发、测试、生产环境不同,这个时候同一个属性在不同环境下就可能配置不同的value,获取application.properties 中的属性值很方便。举例:一种情况下,一个webservice请求地址(最近在研究这个,所以举这个例子)在生产环境、测试环境和生产环境是不同的,这个时候就需要在不同的配置文件中写好,因为springBoot的jar包运行时可以通过指定激活文件的方式运行(当然也可以通过指定配置文件里面的值);还有一点就是properties文件和yaml文件是一样的(yml文件在运行的时候最后也会变成properties,下面介绍的这种方式也是通过springBoot中的PropertiesFactory弄得)
java -jar x.jar --spring.profiles.active=test
上面就是激活test环境
<1> application.yml
server:
port: 9400
spring:
profiles:
active: dev
<2> application-dev.yml (开发环境)
#自定义配置,上面可以配置其他
myconfig:
webservice-url: http://10.126.16.57:7001/services/CallService?wsdl
batchconfig:
query-number: 200
# 单位毫秒
sleep-time: 500
connection-timeout: 60000
receive-timeout: 120000
<3> application-test.yml ( 测试环境)
#自定义配置,上面可以配置其他
myconfig:
webservice-url: http://10.126.16.27:7001/services/CallService?wsdl
batchconfig:
query-number: 500
# 单位毫秒
sleep-time: 1000
connection-timeout: 30000
receive-timeout: 120000
<4> 修改后的PropertiesUtil.java
package com.zlc.springcloud.util;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.configuration.PropertiesConfiguration;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import java.io.*;
@Component
public class PropertiesUtil {
private static final Logger log = LoggerFactory.getLogger(PropertiesUtil.class);
private final Environment env;
public PropertiesUtil(Environment env) {
this.env = env;
}
/**描述: 获取激活配置文件的value
*@param key 键值
*@return : env.getProperty(key) value值
*@Author :追到乌云的尽头找太阳
*创建时间:2019/9/6
*/
public String getPropertiesValue(String key) throws Exception {
if (env.containsProperty(key)){
return env.getProperty(key);
}else {
// 没找到对应的值,调用该方法的地方需要捕获异常,否则返回(null),根据自己的情况弄
throw new Exception();
}
}
public String getPropertiesValue( String propertiesName , String key){
Configuration propertiesConfig ;
String properties = propertiesName+".properties";
String value ;
//返回properties中的参数
try {
propertiesConfig = new PropertiesConfiguration(properties);
value = propertiesConfig.getString(key);
if (null== propertiesConfig.getString(key) || "".equals(propertiesConfig.getString(key))) {
log.error( "获取 {} 配置文件中key为 {} 的值不存在" ,properties, key );
}else {
return value;
}
} catch (ConfigurationException e) {
log.error("读取配置文件异常,异常信息为:"+ e);
e.printStackTrace();
value = null;
}
return value;
}
}
如果你激活了dev ,那么你调用这个方法获取webservice的地址就是在dev环境下的;为什么没用@Value注解呢?因为@Value 一直都是获取application.yml文件下的,也就是一直返回null,所以没用,况且不能判断是否含有这个key,就使用了上面的方法。
@Value("${myconfig.webservice-urll}")
private String url;
这种方式获取application.yml文件下是能成功的,但是无法根据不同的环境获取不同的值,也没什研究。
补充:通过 @Configuration
@ConfigurationProperties(prefix = “config”)
直接添加到类上,prefix = "batch-config"是获取application-xxx文件的中配置参数前缀的,这个方法简单。@ConfigurationProperties(prefix = “config”)注解也可以放到方法上。
package com.springcloud.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author : 追到乌云的尽头找太阳
**/
@Configuration
@ConfigurationProperties(prefix = "batch-config")
public class BatchConfig {
private String queryNumber;
private String sleepTime;
public String getQueryNumber() {
return queryNumber;
}
public void setQueryNumber(String queryNumber) {
this.queryNumber = queryNumber;
}
public String getSleepTime() {
return sleepTime;
}
public void setSleepTime(String sleepTime) {
this.sleepTime = sleepTime;
}
}
application-dev中如下:
batch-config:
query-number: 200
# 单位毫秒
sleep-time: 500
使用的时候只需要通过get方法就能获取到值。