JDK 8
Spring Boot 2.4.5
---
Spring Boot的配置系统 可以分为 2部分:1、自动化配置,2、外部化配置。
说明:
本文主要参考 官方文档 的相关章节编写,尽量写程序测试,内容较多,持续更新(a.k.a 未完待续)。
自动化配置
是指 根据项目的依赖包(特制的)做不同的配置,通过使用 @EnableAutoConfiguration 或 @SpringBootApplication 来使能自动化配置。其中,@SpringBootApplication 使用 @EnableAutoConfiguration 注解过。
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
...
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
...
}
注意 @EnableAutoConfiguration 的 @Import(AutoConfigurationImportSelector.class)。
以上 @EnableAutoConfiguration 、 @SpringBootApplication 、 AutoConfigurationImportSelector 均来自 spring-boot-autoconfigure 包。
这个下面包含一些 子包,就是用来实现 不同模块的自动化配置的——已集成的。
当然,集成默认使用的是 项目所在主机的地址的各种服务——localhost。
通过分析(调试)启动类的运行——SpringApplication.run(Prj1Application.class, args),可以知道何时用到了 AutoConfigurationImportSelector 去实现自动配置的功能。
Spring Boot标准的自动化配置依赖包 都有一个 starter 在名字里面,不同的starter对应不同的 模块,将这些依赖包添加到 pom.xml 即可。
自动化配置 是 非侵入性 的,开发人员 可以使用自己的配置替换掉;
如果不想使用某些自动化配置类,也可以排除它:exclude属性——也是 @EnableAutoConfiguration 的属性
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
类不在 classpath 里面的话,还可以使用 excludeName 属性。
在官文“Appendix C: Auto-configuration Classes” 中,其中展示了 S.B. 支持的自动配置类,分别来自两个模块:
the spring-boot-autoconfigure module
the spring-boot-actuator-autoconfigure module
外部化配置
通过外部化配置,可以实现Java程序相同的代码运行在不同的环境下。
外部配置源有很多,比如,Java的properties文件、YAML文件、环境变量、命令行参数等等。
外部配置 中的属性值,可以使用 @Value、@ConfigurationProperties 和 Spring的 Environment 对象获取。
关于 Environment对象,很多配置中的属性都会 保存到其中,但某些可以配置为 不保存其中,后面再做介绍。使用方式如下:
@Autowired
private Environment env;
属性来源 有很多,优先级高的会 覆盖(override) 优先级低的来源的配置。
下面按照 优先级从低到高(↑) 的顺序 列举 了 属性来源(不全是 外部化配置):
1. Default properties (specified by setting SpringApplication.setDefaultProperties).
public static void main(String[] args) {
// SpringApplication.run(Prj1Application.class, args);
// 改造
SpringApplication sapp = new SpringApplication(Prj1Application.class);
Map<String, Object> params = new HashMap<>(4);
// 添加参数p1
params.put("p1", "first param");
sapp.setDefaultProperties(params);
sapp.run(args);
}
2. @PropertySource annotations on your @Configuration classes.
Please note that such property sources are not added to the Environment until the application
context is being refreshed. This is too late to configure certain properties such as logging.*
and spring.main.* which are read before refresh begins.
3. Config data (such as application.properties files)
在application.properties 添加 下面的内容,将覆盖上面的 p1的值:
p1=p1 in application.properties
注,等号后面的值 没有 引号。
注,针对这一条,下面还将做分析。
4. A RandomValuePropertySource that has properties only in random.*.
5. OS environment variables.
系统环境变量。
注,在使用Eclipse时,重启Eclipse可以使用 更新后(添加、修改)的环境变量。
6. Java System properties (System.getProperties()).
System.getProperty("p1") 可以获取。
Eclipse中配置如下:-Dp1="p1 in Java System properties"
7. JNDI attributes from java:comp/env.
8. ServletContext init parameters.
9. ServletConfig init parameters.
10. Properties from SPRING_APPLICATION_JSON (inline JSON embedded in an environment variable or
system property).
11. Command line arguments.
在使用的Eclipse中添加下面的参数:--p1="p1 in command line"
打包项目,然后,使用java命令运行,也可以输入命令行参数。
>java -jar prj1-0.0.1-SNAPSHOT.jar --p1="p1 in command line"
注,等号后面的值 有引号。
12. properties attribute on your tests. Available on @SpringBootTest and the test annotations for
testing a particular slice of your application.
测试相关。
13. @TestPropertySource annotations on your tests.
测试相关。
14. Devtools global settings properties in the $HOME/.config/spring-boot directory when devtools is active.
和 Spring Boot DevTools 功能有关。
针对上面的第三条(Config data),配置文件 可以存放在不同的位置,下面按照 优先级从低到高(↑) 的顺序展示:
1. Application properties packaged inside your jar (application.properties and YAML variants).
项目的 /src/main/resources 下的 application.properties 或 yml文件。
2. Profile-specific application properties packaged inside your jar (application-{profile}.properties and YAML variants).
项目的 /src/main/resources 下的 application-{profile}.properties 或 yml文件。
# application.properties 文件
spring.profiles.active=dev
p1=p1 in application.properties
# application-dev.properties 文件
p1=p1 in application-dev.properties
如上面的示例,启动后,application-dev.properties 中的 p1值有效(在其它 更高级别的优先级 属性源配合的情况下,比如,命令行)
3. Application properties outside of your packaged jar (application.properties and YAML variants).
jar包外的 的 application.properties 或 yml文件。
外部的,哪里呢?应用的classpath下。一般情况下,classpath会包含 当前目录(.),此时,在某个目录下 存在 配置配置文件(比如,application.properties)的话,会优先使用这个里面的配置。——存疑,见后面的官文 4.2.3。
java -jar app.jar
4. Profile-specific application properties outside of your packaged jar (application-{profile}.properties and YAML variants).
jar包外的 application-{profile}.properties 或 yml文件。
疑问:
一个目录下,同时有 properties 和 YAML 文件,哪个优先级更高呢?properties文件 优先!
官方文档中,外部化配置 下 还有下面的 小节(持续更新):
4.2.1. Accessing Command Line Properties
命令行属性,前面排行 11,以 两个短横线(--)开头,比如,--server.port=9000。
命令行参数会 存放到 Environment对象 中。
代码中执行下面的代码后,可以去下 存放到 Environment对象 中:
// 禁止添加 命令行参数到 Environment对象
sapp.setAddCommandLineProperties(false);
4.2.2. JSON Application Properties
spring boot 把一些属性包装成 JSON块。
spring.application.json 或 SPRING_APPLICATION_JSON属性
用法:
#UN*X
$ SPRING_APPLICATION_JSON='{"acme":{"name":"test"}}' java -jar myapp.jar
$ java -Dspring.application.json='{"acme":{"name":"test"}}' -jar myapp.jar
$ java -jar myapp.jar --spring.application.json='{"acme":{"name":"test"}}'
# JNDI variable
# 不懂
java:comp/env/spring.application.json
4.2.3. External Application Properties
外部应用属性。
spring boot 会从 下面几个位置 寻找(加载,load) application.properties和application.yaml:
1. The classpath root
类路径根目录下——疑问:这是什么地方?
2. The classpath /config package
类路径根目录下的 /config 包。
3. The current directory
当前目录。
4. The /config subdirectory in the current directory
当前目录 下的 /config 子目录。
5. Immediate child directories of the /config subdirectory
(当前目录下?)/config子目录 下的 直接子目录。
注:未验证。
修改文件名称:--spring.config.name
# 官文
$ java -jar myproject.jar --spring.config.name=myproject
指定配置文件存储位置:--spring.config.location
# 官文
$ java -jar myproject.jar
--spring.config.location=optional:classpath:/default.properties,optional:classpath:/override.properties
这一小节还有更多内容:
Optional Locations、
Wildcard Locations(通配符)、
Profile Specific Files、
Importing Additional Data(spring.config.import)、
Importing Extensionless Files、
Using Configuration Trees、
Property Placeholders、
Working with Multi-Document Files、
Activation Properties、
注:spring.profiles.active 可以配置多个值,比如,prod,live,此时,profile相关配置文件 application-prod.properties 中的配置 会被 application-live.properties 中的覆盖(ascii中,l 比 p 靠前)。
注:不设置 spring.profiles.active,此时,使用 default,application-default.properties 会被使用。
注:Property Placeholders(属性占位符):
# 常用 ${app.name}
app.name=MyApp
app.description=${app.name} is a Spring Boot application
注:Working with Multi-Document Files(多文档):
# YAML
使用 三个短横线(---) 分开
#Properties
使用 井号和三个短横线(#---) 分开
未完待续,TODO
4.2.4. Encrypting Properties
加密属性。
spring boot没有提供内在支持,但提供了 EnvironmentPostProcessor 接口用来更新 Environment。
4.2.5. Working with YAML
使用 YAML 文件 取代 properties文件。
直接加载YAML文件:
YamlPropertiesFactoryBean --> Properties
YamlMapFactoryBean --> Map
4.2.6. Configuring Random Values
RandomValuePropertySource
#官文
my.secret=${random.value}
my.number=${random.int}
my.bignumber=${random.long}
my.uuid=${random.uuid}
my.number-less-than-ten=${random.int(10)}
my.number-in-range=${random.int[1024,65536]}
4.2.7. Type-safe Configuration Properties
使用 @Value 可以注入属性值:@Value("${property}")。
但上面的方式会显得繁琐,尤其是在 有很多属性时。
本小节内容较多,暂列入各小小节的标题:
1、JavaBean properties binding
2、Constructor binding
3、Enabling @ConfigurationProperties-annotated types
4、Using @ConfigurationProperties-annotated types
5、Third-party Configuration
6、Relaxed Binding
7、Merging Complex Types
8、Properties Conversion
9、@ConfigurationProperties Validation
10、@ConfigurationProperties vs. @Value
参考文档
2、Spring Boot官方手册(Reference Doc.)
参考:3.4. Auto-configuration 和 4.2. Externalized Configuration 节。
参考文档的版本是 Spring Boot 2.4.5,如文首所言。
官文 中的 4.29. Creating Your Own Auto-configuration、9.2. Properties and Configuration、Appendix C: Auto-configuration Classes 也是和配置相关的,本文暂未介绍。
3、
版本:
1、v0.8.0 2021-08-12 22:02