3.1 配置文件
Spring Boot会按顺序读取各种配置,例如命令行参数、系统参数等。这一节我们讲述配置文件的读取。新建一个名称为“config-file-test”的Web项目,加入以下依赖:
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
对配置文件的测试,会在项目中进行,其只是一个使用Spring Boot构建的Web项目。
3.1.1 默认配置文件
Spring Boot会读取名称为application.properties或者application.yml的文件。在默认情况下,会按照以下顺序读取application.properties(yml)配置文件(如图3-1所示):
1 项目根目录的config目录
2 项目根目录
3 项目classpath下的config目录
4 项目classpath根目录
图3-1 配置文件读取顺序
既然Spring Boot会按顺序读取这4份配置文件,那么如果同一个配置项出现在多份配置文件中,后读取的值是否会覆盖前面读取的值呢?经笔者测试,是不会覆盖的。我们在4份application.yml文件里面,加入测试的配置项:
user: test: name: 1 # 按读取的顺序来配置属性值
加入的配置项的key为user.test.name,属性值分别是4份配置文件的读取顺序。编写启动类和控制器,读取这个配置项,见代码清单3-1。
代码清单3-1:codes\03\3.1\config-file-test\src\main\java\org\crazyit\boot\FileApp.java
@SpringBootApplication @RestController public class FileApp { public static void main(String[] args) { new SpringApplicationBuilder(FileApp.class).run(args); } @Autowired private Environment env; @GetMapping("/ua") public String getProp() { System.out.println(env.getProperty("user.test.name")); return ""; } }
代码清单3-1将应用启动类和控制器放到一起,并注入了Environment实例,这是Spring框架的环境类,可以使用它来读取配置项。运行FileApp后,打开浏览器访问http://localhost:8080/ua,可以看到控制台输出为1,这表示config-file-test/config/application.yml(第1顺位的配置文件)的user.test.name属性被读取,其他配置文件的user.test.name属性值并没有覆盖第1顺位配置文件的属性值。
3.1.2 指定配置文件
如果想让Spring Boot加载我们自已的配置文件,则可以在Spring Boot的启动命令中加入参数,见代码清单3-2。
代码清单3-2:codes\03\3.1\config-file-test\src\main\java\org\crazyit\boot\SpecFileApp.java
new SpringApplicationBuilder(SpecFileApp.class) .properties( "spring.config.location=classpath:/test-folder/my-config.properties") .run(args);
启动类在配置SpringApplicationBuilder时,使用了spring.config.location属性来指定配置文件的位置。除了可以指定配置文件的位置外,还可以使用spring.config.name属性来指定配置文件的名称,例如以下代码片断:
new SpringApplicationBuilder(FileName.class).properties( "spring.config.name=abc").run(args);
以上代码片断指定了配置文件的名称为abc,那么Spring Boot将会到classpath下寻找abc.properties(.yml)文件。一般情况下我们不需要特别指定配置文件,笔者习惯于在项目的src/main/resources下使用application.properties(.yml)文件来进行配置。
3.1.3 yml文件
YAML语言可使用一种方便的格式进行数据配置,通过配置分层、缩进等格式,来增强配置文件的可读性。使用YAML语言的配置文件以“.yml”作为后缀,代码清单3-3即是一个yml配置文件示例。
代码清单3-3:codes\03\3.1\config-file-test\src\main\resources\my-config.yml
jdbc: user: root passwd: 123456 driver: com.mysql.jdbc.Driver
需要特别注意的是,每一行配置的缩进要使用空格,不能使用Tab键进行缩进。代码清单3-3对应的properties文件内容如下:
jdbc.user=root jdbc.passwd=123456 jdbc.driver=com.mysql.jdbc.Driver
注意:如无特别说明,本书的大部分项目会使用yml文件进行配置。
3.1.4 使用profile指定配置
在实际应用中,有时我们可能需要根据特定的环境来激活不同的配置,针对这样的情况,可以考虑使用profile特性。在代码清单3-4的yml文件中定义了两个profile。
代码清单3-4:codes\03\3.1\config-file-test\src\main\resources\test-profile.yml
spring: profiles: mysql jdbc: driver: com.mysql.jdbc.Driver --- spring: profiles: oracle jdbc: driver: oracle.jdbc.driver.OracleDriver
两个profile之间使用“---”进行分隔。接下来,编写启动类来设置激活的profile,见代码清单3-5。
代码清单3-5:codes\03\3.1\config-file-test\src\main\java\org\crazyit\boot\TestProfile.java
@SpringBootApplication
@RestController
public class TestProfile {
public static void main(String[] args) {
// 读取控制台输入
Scanner scan = new Scanner(System.in);
String profile = scan.nextLine();
new SpringApplicationBuilder(
TestProfile.class)
.properties(
"spring.config.location=classpath:/test-profile.yml")
.profiles(profile).run(args);
}
@Autowired
private Environment env;
@GetMapping("/tp")
public String getProp() {
System.out.println(env.getProperty("jdbc.driver"));
return "";
}
}
在代码清单3-5中,先读取控制台的输入,再调用profiles方法来设置需要激活的profile。在启动应用时,在控制台中输入mysql,打开浏览器访问http://localhost:8080/tp,可以看到控制台输出为:com.mysql.jdbc.Driver。除了使用profiles方法外,还可以通过设置spring.profiles.active属性来设置激活的profile,效果与使用profiles方法一致。
除此之外,还可以通过配置文件的名称来设置profile,例如在classpath下有两份文件:application-mysql.yml和application-oracle.yml,这实际上就等于定义了mysql和oracle两个profile。在启动应用时,只需要输入相应的文件名称即可激活它,而且在配置文件中,也不再需要设置spring.profiles属性。