整理翻译了Spring官网的关于配置的加载顺序
配置加载顺序(优先级从高到低):
- 开启DevTools时,~/.spring-boot-devtools.properties
- 测试类上的@TestPropertySource注解
- @SpringBootTest#properties 属性
- 命令行参数 (例:–server.port=8081)
- SPRING_APPLICATION_JSON中的属性
- ServletConfig 初始化参数
- ServletContext 初始化参数
- java:comp/env中的JNDI属性
- System.getProperties()
- 操作系统环境变量
- random.*涉及到的RandomValuePropertySource
- jar包外部的 application-{profile}.properties 或 .yml
- jar包内部的 application-{profile}.properties 或 .yml
- jar包外部的 application-properties 或 .yml
- jar包内部的 application-properties 或 .yml
- @Configuration 类上的 @PropertySource
- SpringApplication.setDefaultProperties()设置的默认属性
注:该加载顺序是指的配置项的生效顺序,不是文件的初始读取顺序
关于application.properties的位置
默认位置:
- ./config
- ./
- classpath中的 /config
- classpath中的 /
修改名字或路径:
- spring.config.name
- spring.config.location
- spring.config.additional-location
Relaxed Binding 机制
自定义配置方式
-
方法一
使用@Value("${property}")注解,配合@Configuration和@PropertySource注解@Configuration用于定义配置类,可替换xml配置文件,被注解的类内部包含有一个或多个被@Bean注解的方法,这些方法将会被AnnotationConfigApplicationContext或AnnotationConfigWebApplicationContext类进行扫描,并用于构建bean定义,初始化Spring容器。
@Configuration注解的配置类有如下要求:
1. @Configuration不可以是final类型
2. @Configuration不可以是匿名类
3. 嵌套的configuration必须是静态类通过@PropertySource注解将properties配置文件中的值存储到Spring的 Environment中,Environment接口提供方法去读取配置文件中的值,参数是properties文件中定义的key值。
@Configuration //可以用@Component替换
@PropertySource(value = "classpath:config/influxdb.properties")
@Slf4j
public class InfluxdbConfig {
@Value("${influxdb.url}")
private String url;
@Value("${influxdb.port}")
private String port;
@Value("${influxdb.username}")
private String username;
@Value("${influxdb.password}")
private String password;
@Value("${influxdb.db}")
private String dbName;
@Bean(name = "influxdb")
public InfluxDB InfluxdbConnect(){
log.info("influxdb : connectting to "+"http://"+url+":"+port);
InfluxDB influxDB = null;
influxDB = InfluxDBFactory.connect("http://"+url+":"+port, username, password);
if (influxDB != null){
log.info("influxdb : connect success");
return influxDB;
}
return null;
}
public String getDbName(){
return dbName;
}
}
influxdb.properties文件内容:
influxdb.url=
influxdb.port=
influxdb.username=
influxdb.password=
influxdb.db=
-
方法二
使用@Value("${property}")注释注入配置属性有时会很麻烦,尤其是在使用多个属性或数据本质上是分层的情况下。Spring Boot提供了一种使用属性的替代方法,该方法允许强类型bean管理和验证应用程序的配置。使用@ConfigurationProperties注解
由于@ConfigurationProperties注解中的location属性在spring boot 1.4以上版本中被去除,因此可以用@PropertySource注解来替代
但@ConfigurationProperties注解无法将标注的类实例化到spring容器中,因此需要@Component注解来实现
@Component //可以用@Configuration 替换
@ConfigurationProperties(prefix = "influxdb")
@PropertySource(value = "classpath:config/influxdb.properties")
@Slf4j
public class MyInfluxdbConfig {
private String url;
private String port;
private String username;
private String password;
private String dbName;
@Bean(name = "influxdb")
public InfluxDB InfluxdbConnect(){
log.info("influxdb : connectting to "+"http://"+url+":"+port);
InfluxDB influxDB = null;
influxDB = InfluxDBFactory.connect("http://"+url+":"+port, username, password);
if (influxDB != null){
log.info("influxdb : connect success");
return influxDB;
}
return null;
}
//Getter and Setter ...
}
influxdb.properties文件内容同方法一
需要注意的是虽然@Component 和 @Configuration 可以互相替换,但它们还是有差别的:
@Configuration 中所有带 @Bean 注解的方法都会被动态代理(带有@Configuration 注解的 bean 都已经变成了增强的类),因此调用该方法返回的都是同一个实例(单例)
但是如果是变成@Component之后,返回的就不是一个实例了,每次都会创建一个新的实例