spring boot 框架的初衷是自动化配置,将一坨坨的配置文件收进了抽屉里,让你的项目看起来简洁清爽了起来。但是这些配置并没有消失,而是收纳进了框架内部。项目定制化的配置可以无中生有的装配到项目中,在容器中可以直接使用。加载配置有多种方式,做一个记录。
spring boot 默认会从 src/main/resources
和 src/main/resources/config
路径中加载 application.properties、application.yml
配置文件,作为默认配置。
使用 @Value
注解,在容器范围内的任一变量上,可以直接加载一个配置到该变量。 @Value
注解在 Bean
加载之后自动执行。
例如在配置文件application.properties中写如下一个配置项
#application.properties
port=9000
在本个配置类中加载该配置
//AppServiceConfig.java
@Configuration
@Data
public class AppServiceConfig {
@Value("${port}")
private Integer port;
}
在主类中查看这个配置
// ConfigrApplication.java
@SpringBootApplication
public class ConfigrApplication implements CommandLineRunner {
@Autowired
private AppServiceConfig config;
public static void main(String[] args) {
SpringApplication.run(NettyServerApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
System.out.println(config);
}
}
在配置文件中修改配置项目为:port=9000
,在配置类中修改为 @Value("${app.port}")
,执行程序查看结果,仍然正确加载了配置。
如果在加载代码中加载了一个不存在的配置,可以指定一个默认值,例如 @Value("${app.port:9000}")
,同时在配置文件中删掉 port 配置项,启动系统会看到 port 已经配置成了默认值。
每次配置一个配置项在有些复杂配置中不够简洁,是否可以指定一个规则自动的配置出一个对象的所有属性呢,答案当然是可以。
使用 @ConfigurationProperties
注解在配置对象上,可以自动的同名属性配置化。
#application.properties
app.port=9000
app.timeout=120
app.node=master
在本个配置类中加载该配置
//AppServiceConfig.java
@Configuration
@ConfigurationProperties(prefix = "app")
@Data
public class AppServiceConfig {
private Integer port;
private Integer timeout;
private String node;
@PostConstruct
public void PostConstruct(){
System.out.println("@PostConstruct");
System.out.println(this);
}
}
可以直接装配 Map、List等类型的对象,示例如下:
#application.properties
app.port=9000
app.timeout=120
app.node=master
#map
app.map[k1]=v1
app.map[k2]=v2
#list
app.list[0]=l1
app.list[1]=l2
在本个配置类中加载该配置
//AppServiceConfig.java
@Configuration
@ConfigurationProperties(prefix = "app")
@Data
public class AppServiceConfig {
private Integer port;
private Integer timeout;
private String node;
private Map<String, String> map;
private List<String> list;
@PostConstruct
public void PostConstruct(){
System.out.println("@PostConstruct");
System.out.println(this);
}
}
可以看到已经加载了复杂对象。
默认的配置项都在主配置文件 (application.properties、application.yml)
中,为了更清晰的分离配置,可以通过 @PropertySource
注解指定配置文件。该注解可以和前两项注解组合使用。
假设将配置项单独放置在 app.properties文件中。
@PropertySource("classpath:app.properties")
使用类路径有一定的加载顺序,一般代码内部包含了这个文件,在外面有同名文件也不会覆盖配置,需要额外注意。
@PropertySource("file:app.properties")
如果在外部配置该文件,推荐用这种方式。
在主配置文件中通过 spring.profiles.include
参数,指定额外的配置文件,与 @PropertySource
注解起到类似的效果,但是更加灵活。但是对于配置文件名需要符合 application-xx.properties
的格式,例如本实例,将 app.properties
改名为 application-app.properties
。
在主配置文件中进行配置:
# application.properties
spring.profiles.include=app
在目标配置中写入配置项
# application-app.properties
app.port=9000
app.timeout=120
app.node=master
#map
app.map[k1]=v1
app.map[k2]=v2
#list
app.list[0]=l1
app.list[1]=l2
加载配置类
//AppServiceConfig.java
@Configuration
@ConfigurationProperties(prefix = "app")
@Data
public class AppServiceConfig {
private Integer port;
private Integer timeout;
private String node;
private Map<String, String> map;
private List<String> list;
@PostConstruct
public void PostConstruct(){
System.out.println("@PostConstruct");
System.out.println(this);
}
}