SpringBoot 干货教程 | 第四章:SpringBoot 配置详解
基于 SpringBoot 的约定优于配置的原则,在多数情况下,启动一个应用时,基本上无需做太多的配置,应用就能正常启动。
但在大部分开发环境下,添加额外配置是无所避免的,比如自定义应用端口号、mq 的服务地址、缓存服务的服务地址、数据库的配置等,都或多或少的需要一些外部的配置项。
配置文件简述
SpringBoot 默认的全局配置文件名为 application.properties
或者 application.yml
(Spring 官方推荐使用的格式是 .yml
格式,目前官网都是实例都是使用 yml 格式进行配置讲解的),应用启动时会自动加载此文件,无需手动引入。
但是在 Initializr 或者 IDEA 生成工程的时候都是生成了 application.properties
配置文件,可能还是考虑到大多数人的使用习惯。其实都是一样的东西,没什么好纠结的,喜欢用哪一种配置文件就选择哪一种。
配置文件编码
由于 SpringBoot 在读取 properties
文件时,使用的是 PropertiesPropertySourceLoader
类进行读取,默认读取的编码是 ISO8859-1
,故在默认的配置文件中使用中文时,会出现乱码,此时可以将中文转成 Unicode 编码或者使用 yml
配置格式(yml 默认支持 utf-8)。
或者可以将作为配置写入到一个自定义配置文件,利用 @PropertySource
注解的 encoding
属性指定编码,假如你的配置文件编码为 GBK
。
@SpringBootApplication
@PropertySource(value={ "classpath:blog.properties" }, encoding="GBK")
public class SpringbootConfigApplication
{
public static void main(String[] args)
{
SpringApplication.run(SpringbootConfigApplication.class, args);
}
}
如果必须使用 properties
文件,我们的教程就是这样使用的。在 IDEA 中,选择菜单 File->Settings->Editor->File encodings,在 Properties Files (*.properties) 配置中,在 Default encoding for properties files 后面选择 UTF-8
,勾选 Transparent native-to-ascii conversion
。如下图所示:
注意,如果你已经写好了配置文件,并且包含中文,那么在上述配置前先复制一份配置内容,在配置好后重新粘贴进来,因为在上述配置后中文转换编码会变成乱码。
自定义属性值配置
application.properties
配置文件支持自定义属性的支持,比如:
blog.address=https://www.daimafans.com
blog.author=谦谦君子
blog.desc=代码饭 www.daimafans.com 全面、专业的源代码分享网站,编程技术分享网站
然后可通过 Spring @value
注解 @Value("${blog.author}")
的形式获取属性值。
@RestController
public class ConfigController {
@Value("${blog.address}")
String address;
@Value("${blog.author}")
String author;
@Value("${blog.desc}")
String desc;
@RequestMapping("/")
public String blog()
{
return address + "<br>" + author + "<br>" + desc;
}
}
现在启动项目,访问 http://127.0.0.1:8080/
工程中自定义属性时,特别是一些公共包,建议在 /src/main/resources/META-INF
下创建 spring-configuration-metadata.json
属性元文件。
这样在 IDEA 中使用时,输入的时候会进行联想提示,包括属性名和属性说明,这样也方便调用者询问属性名和属性含义。
需要注意的是,想要顺利的使用这个特性,需要加入 spring-boot-configuration-processor
依赖。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
有关 configuration metadata 的介绍可以回顾教程 SpringBoot 干货教程 | 第一章:教程目录大纲和前戏 小节 “starter 与 metadata”,更详细的内容可以参阅官方文档 Appendix B. Configuration Metadata。
属性引用
在配置文件中,一个属性的值可以引用另外一个属性的值,例如:
blog.address=https://www.daimafans.com
blog.author=谦谦君子
blog.desc=代码饭 www.daimafans.com 全面、专业的源代码分享网站,编程技术分享网站
blog.info=${blog.address}<br>${blog.author}<br>${blog.desc}
修改 ConfigController
类为:
@RestController
public class ConfigController
{
@Value("${blog.address}")
String address;
@Value("${blog.author}")
String author;
@Value("${blog.desc}")
String desc;
@Value("${blog.info}")
String info;
@RequestMapping("/")
public String blog()
{
// return address + "<br>" + author + "<br>" + desc;
return info;
}
}
重启工程,再次访问 http://127.0.0.1:8080/
,和我们上面得到的结果一样!
随机数
SpringBoot 的属性配置文件中可以通过 ${random}
来产生 int
、long
或 string
等值,来支持属性的随机值。
# 随机字符串
.random.value=${random.value}
# 随机 int
.random.number=${random.int}
# 随机 long
.random.bignumber=${random.long}
# 10 以内的随机数
.random.test1=${random.int(10)}
# 1-20 的随机数
.random.test2=${random.int[1,20]}
我们在 ConfigController
新增 random
方法:
@RestController
public class ConfigController
{
@Value("${.random.test2}")
int test2;
@RequestMapping(value = "random", method = RequestMethod.GET)
public String random()
{
return String.valueOf(test2);
}
}
重启工程,现在访问 http://127.0.0.1:8080/random
,得到一个随机数,在 1 到 20 之间,需要注意,这个配置文件中的随机数实在工程启动的时候生成的,之后不会再变化,除非重新启动工程。
不知道你有没有这个疑问,上面的随机数配置属性的键名是以 .
开头的,这是为什么呢?如果不添加的话会是什么样子的呢?
其实没什么特别的玄妙之处,就是我们不小心用到了不该用的配置名称,具体可以查看 org.springframework.boot.env.RandomValuePropertySource
源码:
public class RandomValuePropertySource extends PropertySource<Random> {
public static final String RANDOM_PROPERTY_SOURCE_NAME = "random";
private static final String PREFIX = "random.";
// 省略其它
}
我们使用的键名前缀和 RandomValuePropertySource
环境变量名称前缀重复了,所以我们在使用 @value
标签取值的时候,取回来的是一个 32 位的 uuid。我们把随机数配置部分的键名前缀修改为其它字符串,比如 rnd
。
# 随机字符串
rnd.value=${random.value}
# 随机 int
rnd.number=${random.int}
# 随机 long
rnd.bignumber=${random.long}
# 10 以内的随机数
rnd.test1=${random.int(10)}
# 1-20 的随机数
rnd.test2=${random.int[1,20]}
自定义配置文件
在多数情况下,配置信息基本上都是放入 application.properties
文件中。
但在一些场景下,比如某个配置项比较多时,为了分开存放,也可自定义配置文件,如 blog.properties
。
由于自定义的文件,系统不会自动加载,这个时候就需要手动引入了。
利用 @PropertySource
注解可以引入单个或多个配置文件,在查分为多个配置文件的时候,需要引入多个配置文件,可使用 @PropertySources
设置配置文件数组,引入多个文件。
@SpringBootApplication
@PropertySource(value="classpath:blog.properties", encoding="utf-8")
public class SpringbootConfigApplication
{
public static void main(String[] args)
{
SpringApplication.run(SpringbootConfigApplication.class, args);
}
}
可以看到,我们把 @PropertySource
注解作用在 SpringBoot 启动入口类上,指定的配置文件为 blog.properties
,在当前工程的 classes
下加载,文件的编码为 utf-8
。正如上面所说的配置文件编码问题,一般正常情况下新建的 properties 文件的编码都是操作系统本地编码,我们的中文电脑都是 gbk
,如果你不想或不便在 IDEA 中设置编码转换,可以在这里指定文件编码格式。
如果有多个配置文件,可以使用数组的方式引入文件。
@SpringBootApplication
@PropertySource(value={ "classpath:blog.properties", "classpath:redis.properties" }, encoding="utf-8")
public class SpringbootConfigApplication
{
public static void main(String[] args)
{
SpringApplication.run(SpringbootConfigApplication.class, args);
}
}
配置绑定对象
虽然使用 @Value()
方式能方便的引入自定义的属性值,但在多某个配置项属于某一配置集合时,希望对应到一个实体配置类中,SpringBoot 对这种场景也提供了支持。利用 @ConfigurationProperties
属性,即可完成 properties 配置的映射:
config.number=1
config.name=谦谦君子
config.hobby[0]=编程
config.hobby[1]=小姐姐
实体类:
@Component
@ConfigurationProperties(prefix="config")
// @EnableConfigurationProperties(value= {Config.class})
public class Config {
private String number;
private String name;
private List<String> hobby;
// 省略 setter/getter
}
这里可直接加入 @Component
注解使 Config
在启动时被自动扫描到,或者使用 @EnableConfigurationProperties
注解注册此实体 bean。
其次,在引入 @ConfigurationProperties
时,如果你前面没有加,这里 IDE 会再次提示你引入 spring-boot-configuration-processor
依赖,前面提到,在自定义属性时,创建 spring-configuration-metadata.json
可进行属性提示,而此依赖功能类似,会编译时自动生成 spring-configuration-metadata.json
文件,此文件主要给 IDE 用于提示使用。添加后在配置文件点击属性时,会自动跳转到对应绑定的实体类中。
我们这里增加一个 /config
请求:
@RestController
public class ConfigController
{
@Autowired
Config config;
@GetMapping(value = "config")
public Config config()
{
return config;
}
}
重启工程,访问 http://127.0.0.1:8080/config
。
本文收录在 SpringBoot 干货系列教程:SpringBoot 干货教程 | 第一章:教程目录大纲和前戏