本文已参与「新人创作礼」活动,一起开启掘金创作之路。
全局配置文件
Spring Boot 项目使用一个全局的配置文件 application.properties 或 application.yml进行参数的配置。该文件保存在resources目录下或者 classpath 下的 /config目录下.
文件格式
如果是 application.properties 格式:
#修改 Tomcat 的端口为 8088
server.port=8088
#修改进入DispatcherServlet的规则为 *.html
server.servlet-path=*.html
如果是 application.yml 格式:
server:
port: 8081
servlet-path: *.html
更多默认可配置项:docs.spring.io/spring-boot…
属性配置占位符
支持引用配置中已出现的属性. 格式: ${xx.yy:zz} 表示使用 xx 对象的 yy 属性, zz 用来指定找不到 yy 属性时的默认值.
person.name=张三
person.qianming=${person.name}, 加油!
person.info=${person.name},${person.sex:男},${person.country:中国}
获取配置文件的内容
SpringBoot 提供了四种获取配置文件内容的方式 .
使用 PropertiesLoaderUtils
TODO
使用 @ConfigurationProperties 映射为实体类
对于 SpringBoot 项目,可以很方便的将配置文件中的参数值,映射到指定实体类上去获取使用。
1.导入配置文件处理器依赖, 这样配置文件进行绑定时就会有提示:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
2.配置 application.yml
person:
name: zhangsan
age: 18
birth: 2000/01/25
maps: {k1: v1, k2: v2}
lists:
- lisi
- zhaoliu
dog:
name: 旺财
age: 2
3.对应的实体类 Person
@DNAA
// 注意: 只有当这个类是容器的组件时, 才可以使用该注解.
@Component
// 该注解告诉 SpringBoot 将本类中的所有属性和配置文件中以 person 开头的配置进行绑定.
@ConfigurationProperties(prefix="person")
public class PersonConfig {
private String name;
private Integer age;
private Map<String,Object> maps;
private List<Object> lists;
private Dog dog;
}
4.使用配置值
// 使用
@Autowired
private PersonConfig personConfig; //注入,和上面的 @ConfigurationProperties 注解所在的类的类名相同.
@GetMapping(value = "person")
public Person person(){
return personConfig.getName();
}
5.注意
如果 在 key 中存在 大写字母, 且不是最后一级的, 则会报错. 如果是最后一级, 不会报错.
# 比如 下面 singleMonth 的写法就是错误的
settings:
base:
basePathWin: xxx
singleMonth:
basePath: xxx
#正确写法应该是 singleMonth -> single-month
settings:
base:
basePathWin: xxx
single-month:
basePath: xxx
同时配置类的 prefix 也需要改变 :
@Component
@ConfigurationProperties(prefix = "settings.single-month")
public class SingleMonthConfig {
private String basePath;
}
使用 @Value 注解
比如如下配置:
person:
name: zhangsan
age: 18
如下方式获取:
@Value("${person.name}")
private String name;
// 注意,*.properties 文件中的中文默认以 ISO-8859-1 方式编码
// 因此需要对中文内容进行重新编码
@GetMapping(value = "person")
public String person(){
System.out.println(name);
return name;
}
使用 Environment 类
比如如下配置:
aliyun:
sms:
accessKeyId: xxxxxx
accessKeySecret: yyyyy
template_code: SMS_85735065
sign_name: TS
如下方式获取:
import org.springframework.core.env.Environment;
@Autowired
private Environment env; // 注入 Environment
public String sendSms(String mobile) {
String accessKeyId = env.getProperty("aliyun.sms.accessKeyId");
String accessKeySecret = env.getProperty("aliyun.sms.accessKeySecret");
return "ok";
}
Environment源码 blog.csdn.net/cen50958/ar…
Environment源码 cloud.tencent.com/developer/a…
配置文件的加载顺序
SpringBoot 项目的配置文件分为内部的和外部的.
外部的优先级高于内部的. ( 方便打包之后更改配置 )优先级由高到低,高优先级的配置会覆盖低优先级的配置,没有的配置进行互补配置.
项目内的配置文件加载顺序
SpringBoot 项目启动后,会自动扫描以下位置的 application.properties 或 application.yml 文件,作为默认配置文件 :
./config/( 项目根路径下的 config 文件夹) 下图中的 8081./(项目根路径) 下图中的 8082classpath:/config/(类路径下的 config 文件夹) 下图中的 8083classpath:/(类路径) 下图中的 8084
这几个文件在 IDEA 中的位置如图 :
上面四个位置的配置文件位置,优先级由高到低。
注意:不是类路径下的配置文件在打包时,如果不做配置是不会打包进 jar 包中的,也会是说前两个配置在项目打包时,很容易忽略掉,所以尽量不要用前两个位置.
外部配置文件
外部配置有如下几种方式,并且几个位置的配置文件位置,优先级从高到低,高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置.
- 命令行参数. 所有的配置项都可以在命令行上进行设置.
java -jar springboot-configuration.jar --server.port=8088 --server.servlet.context-path=/spring
- 指定配置文件位置。启动项目时,可以用
spring.config.location指定配置文件的新位置.
java -jar springboot-configuration.jar --spring.config.location=F:/application.properties
- 默认位置. 只要在 jar 包的同级目录, 放置一个 application.properties 或者 application.yml 配置文件,就会自动被使用.
\
读取指定名称的配置文件
上面演示的都是读取 application.yml 这种默认的配置文件,但是所有配置都放在一个文件中,可读性很差,一般都是分开到多个 *.yml 文件中,这又改如何获取呢?
@PropertySource 注解可以加载指定名称的配置件 *.properties 到 Spring 的 Environment 中。这样就可以配合 @Value 和 @ConfigurationProperties 使用。
- @PropertySource + @Value 可以将自定义属性文件中的属性变量值注入到当前类的使用 @Value 注解的成员变量中.
- @PropertySource + @ConfigurationProperties,可以将属性文件与一个 Java 类绑定,将属性文件中的变量值注入到该Java类的成员变量中.
@PropertySource 和 @Value 组合使用
代码在 Github 上的地址:
在 resources 目录下存在一个名叫 config-1.properties 的配置文件,文件内容如下:
# 微信开放平台 appid
wx.open.app_id=wxe54c24e8ff2b2771
# 微信开放平台 appsecret
wx.open.app_secret=677a2d6bd69e88b5d7a2bbf42b6352b3
# 微信开放平台 重定向url
wx.open.redirect_url=https://qasso.huanxi.com/Login/callback
将其读取到项目中的 Config1 类上:
@Component
@PropertySource(value = {"classpath:wxConfig.properties"})
public class ConstantWxUtils implements InitializingBean {
@Value("${wx.open.app_id}")
private String appId;
@Value("${wx.open.app_secret}")
private String appSecret;
@Value("${wx.open.redirect_url}")
private String redirectUrl;
public static String WX_OPEN_APP_ID;
public static String WX_OPEN_APP_SECRET;
public static String WX_OPEN_REDIRECT_URL;
@Override
public void afterPropertiesSet() throws Exception {
WX_OPEN_APP_ID = appId;
WX_OPEN_APP_SECRET = appSecret;
WX_OPEN_REDIRECT_URL = redirectUrl;
}
}
@PropertySource 和 @ConfigurationProperties 组合使用
代码在 Github 上的地址:
注意,这里需要使用 spring-boot-configuration-processor 依赖.
在 resources 目录下存在一个名叫 config-2.properties 的配置文件,文件内容同上.
将其读取到项目中的 Config2 类上:
@Slf4j
@Getter
@Component
@PropertySource(value = {"classpath:config-2.properties"},encoding="utf-8")
@ConfigurationProperties(prefix = "wx.open1")
public class Config2 {
private String appId;
private String appSecret;
private String redirectUrl;
// 使用 set 方法证明配置确实加载了
public void setAppId(String appId) {
this.appId = appId;
log.info("appId= {}", appId);
}
public void setAppSecret(String appSecret) {
this.appSecret = appSecret;
log.info("appSecret= {}", appSecret);
}
public void setRedirectUrl(String redirectUrl) {
this.redirectUrl = redirectUrl;
log.info("redirectUrl= {}", redirectUrl);
}
}
这里遇到了如下几个问题:
- 读取的配置乱码,即使已经对 IDEA 进行了设置,依旧乱码,使用 @PropertySource 注解的
encoding属性指定编码方式. - 虽然 Conifg2 中指定读取 config-2.properties,但是如果 @ConfigurationProperties 注解中的 prefix 属性在其他 config 配置文件中存在的话,还是会错乱,所以这里的
prefix 前缀需要唯一,不然有可能读取到其他配置文件件去.