习惯优于配置
Spring Boot 项目的重要思想就是 "习惯优于配置", 这也是为什么该项目诞生的原因, 让开发者免于 Spring 生态中各种项目的配置. 尽管如此, 但项目中完全零配置还是很难做到的, 因此本篇文章就来讲解一下 Spring Boot 中的配置.
分析默认项目
先从默认创建的项目开始分析, Spring Boot 默认创建的项目会有一个如下所示的入口类, 该类被标注了 @SpringBootApplication 注解, 而该注解相当于 @SpringConfiguration ,@EnableAutoConfiguration 和 @ComponentScan 三个的结合, 由于前两个注解才和配置有关, 所以下面只讲解前两个.
- @SpringBootApplication
- public class DemoApplication {
- public static void main(String[] args) {
- SpringApplication.run(DemoApplication.class, args);
- }
- }
- @EnableAutoConfiguration
若标记了 @EnableAutoConfiguration 注解, Spring Boot 会根据 ClassPath 中的 Jar 包依赖来自动配置程序, 例如添加了 web 相关的依赖则会自动进行 Web 配置, 且注意官方建议将该注解标记且只标记一次在标有 @Configuration 的类上.
由于自动配置是非侵入性的, 因此可以自定义配置来覆盖原有的自动配置, 而且还可以禁止某些自动配置类, 例如下面例子禁止了数据源的自动配置.
- @Configuration
- @EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
- public class DemoConf {
- // ...
- }
- @SpringConfiguration
由源码可知 @SpringConfiguration 是 @Configuration 的别名, 而被 @Configuration 标注的类, 相当于一个配置文件可进行各种自定义配置, 例如下面配置类中注册了一个 Bean .
- @Configuration
- public class AppConf {
- @Bean
- public DemoBean demoBean() {
- return new DemoBean();
- }
- }
属性文件及其优先级
标注 @Configuration 的配置类描述了如何进行配置类似于函数, 而属性文件的属性则相当于参数.
默认情况下配置类会按如下列表从高到低的优先级读取属性文件, 且默认读取文件名为 application.suffix 的属性文件, 其中的 suffix 为 properties 或 YAML 其中之一, 分别代表支持的两种类型文件.
相对打包后程序目录 ./config 下
打包后程序目录下
相对项目资源目录 ./config 下
项目资源目录下
注意优先级高的属性文件中的相同属性, 会覆盖掉优先级低的文件中的属性配置, 例如项目资源目录下有如下文件结构, 根据上述规则最终获取到的 demo.name 的值就为 foo. 这样的设计可以方便利用外部属性文件改变程序某些配置属性, 例如改变绑定端口或者数据库地址.
- /resources
- |- /config
- |- application.properties <- demo.name=foo
- |- application.properties <- demo.name=bar
运行时指定属性
除了可用外部属性文件覆盖内部属性文件的属性, 还可以在运行程序时指定属性, 例如下面命令指定了 demo.name 属性值为 foo.
java -jar demo.jar --demo.name=foo
当然若是不想运行时指定属性, 也可使用 SpringApplication.setAddCommandLineProperties(false) 来禁止读取命令行的属性.
指定属性文件
可利用 @PropertySource 来指定属性文件, 例如下面的例子, 但注意只支持 properties 和 xml 两种类型的属性文件.
- @Configuration
- @PropertySource("classpath:/demo.properties") // or @PropertySource("file:/path/demo.xml")
- public class AppConf {
- // ...
- }
虽然不支持 YAML 等其他类型的文件, 但可以自己实现 PropertySourceFactory 接口 (该特性在 Spring 4.3 中引入), 然后如下面的例子在注解中用 factory 指定实现类, 具体实现参考这篇文章.
- @Configuration
- @PropertySource(value="classpath:/demo.yml", factory=YamlPropertySourceFactory.class)
- public class AppConf {
- // ...
- }
多环境的属性文件
对于不同环境, 只需要创建名为 application-env.sufix 的属性文件, 其中 env 和 suffix 分别为环境名和后缀名, 然后在默认的属性文件 application.suffix 中配置属性 spring.profiles.active=env 即可.
例如创建如下的文件目录结构, 然后在 application.properties 文件中配置属性 spring.profiles.active=dev , 就可以加载名为 application-dev.properties 的属性文件.
- /resources
- |- application.properties
- |- application-dev.properties
- |- application-prod.properties
使用属性
使用 @Value 加 EL 表达式就可以获取属性文件中的属性, 例如下面一个简单的例子.
- /* application.properties 's content */
- // demo.name=foo
- @Configuration
- public class AppConf {
- @Value("${demo.name}")
- private String name;
- }
@Value 注解不支持批量导入属性, 但使用 @ConfigurationProperties 就可以批量导入属性, 例如下面的例子.
- /* application.properties 's content */
- // demo.name=foo
- // demo.addr=bar
- @Configuration(prefix = "demo") // same as @Configuration("demo")
- public class AppConf {
- private String name;
- private String addr;
- // getters and setters
- }
除了能批量导入之外, 其与 @Value 还有其他区别, 具体参考这篇文章.
来源: https://www.cnblogs.com/linzhehuang/p/10617116.html