目录
●自动配置
众所周知,SpringBoot最让人惊喜的地方在于其能自动配置好依赖的框架/组件,省去了传统集成过程中的繁琐的配置过程。最简单的一个SpringBoot工程(从https://start.spring.io/生成)你甚至看不到web.xml,就算application.properties是空的,也依旧能够启动运行。这得益于SpringBoot会根据引入的依赖,自动尝试去配置对应的项。在我们的项目中,表现在@SpringBootApplication 这个注解上,它等同于 @Configuration、@EnableAutoConfiguration加上 @ComponentScan这三个注解(可以替换)。
SpringBoot虽然让大家省去了繁琐的配置工作,但它依旧支持自定义的配置,并且还提供了很丰富的途径,本文基于2.1.0RELEASE版本为大家介绍常见的配置方式。
●SpringBoot支持的自定义配置途径
根据官方手册“Externalized Configuration”一章的内容,我们知道,SpringBoot提供了以下的自定义配置途径,并将从上到下具备前后优先级(越靠前,优先级越高,会覆盖后面的相同配置项)。这意味着,合理搭配使用,我们可以在相对低优先级的配置项上定义好默认配置,相对高的配置项上让用户导入自定义的配置,实现灵活变动,具体下面会说。我们先看看这些自定义配置途径:
- 全局变量:位于~/.spring-boot-devtools.properties,需要启用spring-boot-devtools;
- @TestPropertySource注解:用于测试类中;
- 测试类中的properties:需要测试类用@SpringBootTest注解标识;
- 命令行参数:通常用于命令行运行jar包时传入参数;
- 环境变量SPRING_APPLICATION_JSON中的值;
- ServletConfig的初始化参数;
- ServletContext的初始化参数;
- JNDI中的参数:通过java:comp/env使用;
- Java中的系统属性:通过System.getProperties()使用;
- 操作系统的环境变量;
- 配置文件中的随机项,random.*;
- 外部Profile-specific application properties文件(.properties或者YAML文件);
- 内部Profile-specific application properties文件(.properties或者YAML文件);
- 外部application properties文件(.properties或者YAML文件);
- 内部application properties文件(.properties或者YAML文件);
- @PropertySource注解:用于添加了@Configuration注解的配置类上;
- SpringApplication的默认配置项;
●配置项如何使用
有一些配置项是SpringApplication直接用的,比如启动端口;有些配置项则是我们需要在代码中自己用的。特别是后者,我们如果想在代码中使用,应该怎么办呢?笔者有见过这么写的:
try{
Properties properties = new Properties();
inStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("application.properties");
properties.load(inStream);
appCode = properties.getProperty("appCode");
}
catch (Exception e) {
log.error("初始化配置参数异常", e);
throw new RuntimeException(e);
}
finally{
if(null != inStream){
try {
inStream.close();
} catch (IOException e) {
log.error("关闭字节输入流异常", e);
throw new RuntimeException(e);
}
}
}
说实话,为了读取几个配置项,需要这么长的篇幅,确实不太优雅。SpringBoot给大家提供了非常简洁的方式,只需要两个注解:@Component和@Value("${配置项名称}")即可。例如:
@Component
public class CustomProperty {
@Value("${appCode}")
private String initName;
}
虽然使用两个注解引入配置项使用很方便,但对于需要大面积使用不同配置项的情况,会写很多@Value注解,另外一种解决思路是将配置文件映射成POJO。例如我们在配置文件中加入如下配置项:
# 自定义App配置项
app.name=MyFirstApp
app.code=1
app.description=第一个App
app.security.user=admin
app.security.password=12345
为了将其映射成POJO,我们导入一个依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
最后,我们定义一个POJO类,这样就把它映射过去,利用注解@ConfigurationProperties("app")标识,可以直接用了。其中,注解中的值指的是这些配置项的前缀,这样可以减少类的深度。
@ConfigurationProperties("app")
@Component
public class AppProperties {
private String name;
private String code;
private String description;
private final Security security = new Security();
public class Security{
private String user;
private String password;
/* 篇幅原因,省略get\set方法 */
}
/* 篇幅原因,省略get\set方法 */
}
●全部配置项
SpringBoot支持的配置项可以在官方手册的Appendix A. Common application properties一节中查询到。
●配置项优先级使用示例
我们来举个例子:我们可以在会在application.properties中配置一个系统启动的端口(不配的话默认是8080端口)和一些自定义的配置项:
# 启动端口
server.port=8088
# 自定义配置项
initName=Tommy
appCode=20
然后把项目打成jar包给用户,用户通过命令行-jar加参数(通过--表示)启动,修改启动端口和一些自定义配置项的值(当然,用户也可以传入一个新的application.properties)。
$ java -jar myproject.jar --server.port=8888 --appCode=1
这样启动后,通过http://localhost:8888/就能访问到项目了,并且,我们传入了appCode为1,覆盖了默认项。
●其他细节说明
配置文件中可以使用占位符,如下:
app.name=MyApp
app.description=${app.name} is a Spring Boot application
application.properties配置文件可以位于以下四个路径,从上到下优先级递减:
- 当前目录的/config文件夹下;
- 当前目录;
- classpath的/config文件夹下;
- classpath下;
●小结
对于SpringBoot的配置,最主要的理解两点就可以了,1是配置途径是有优先级的,合理搭配可实现默认值与自定义的灵活变动;2是配置项的使用通过两个注解是非常快捷高效的,如果需要使用的配置项众多,可以将配置文件映射成POJO。至于需要什么样的配置项,还是按图索骥,直接查询给出链接中的相关说明即可,例如配置数据源:
以上,就解决SpringBoot的配置问题。今天,你学会了吗