配置文件
全局配置文件,名称固定写法:
- application.properties
- application.yaml
YAML
一种以数据为中心的标记语言,适合作为配置文件存在;
比起 properties,结构上更适合阅读,具备良好的可视化。
server:
port: 8090
基本语法
- 缩进不同代表层级
- 仅使用空格作为缩进
- 缩进空格不限制,但是同级元素必须相同
- 大小写敏感
最基本的语法:
key: value
注意:值的前面必须至少保留一个空格
支持数据结构
-
对象:键值对的集合
-
普通写法:
key: value1: 123 value2: 456 vlaue3: 789
-
行内写法:
key: {value1: 123, value2: 456, value3: 789}
-
-
数组:一组按次序排列的值
-
使用 - 方式:
array: - 123 - 456 - 789
-
行内方式:
array: [123,456,789]
-
-
字面量:单个的、不可再分的值
- 字符串默认不需要加引号,特殊情况需要处理的按引号不同,处理方式不同:
- 单引号:转义其中的特殊字符
- 双引号:不转义其中的特殊字符
- 字符串可以多行形式,但是从第二行开始必须要有单个空格开头
- 字符串默认不需要加引号,特殊情况需要处理的按引号不同,处理方式不同:
-
支持复合结构
- 不同数据结构内可以嵌套其他数据结构
文档
yaml 单个文件内可以区分不同配置区域,使用 --- 隔开出多个配置区域:
server:
port: 8080
---
server:
port: 8081
占位符
在配置文件中,可以支持默认值:
person.age=${age:18}
在 age 不存在的时候,会将 18 作为值。
同时,可以引用当前配置文件中已定义的配置值:
person.age=18
person.dog.age=${person.age}
随机数值:
SpringBoot 提供了几种随机值:
- random.int
- random.int(vlaue, [max])
- random.long
- random.long(min, [max])
- random.uuid
- random.value
注入配置
支持两种方式注入配置信息:
- @ConfigurationProperties
- @Value
但是,两种方式都需要添加 @Component 注解,保证类是 Spring 的容器 Bean。
@ConfigurationProperties
本地定义的类,若是若是需要外部另外配置的话,可以将其作为一种配置存在,定义在配置文件中,可灵活变化。
要完成这个要求的话,需要在类上面添加两个组件:
- @Component
- @ConfigurationProperties
作为 Spring 组件的类才满足作为外部注入配置的条件之一;
同时,一个类中是需要有对应的 setXXX() 方法,否则是无法完成注入的。
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
//......
}
在 @ConfigurationProperties 中,定义配置的前缀,将正确的配置注入类中。
@Value
@Component
public class Person {
@Value("19")
private Integer age;
@Value("person")
private String name;
}
两种方式的区别
区别 | @ConfigurationProperties | @Value |
---|---|---|
功能 | 批量注入 | 单独注入 |
SpEl 语法 | 不支持 | 支持 |
松散绑定 | 支持 | 不支持 |
JSR 303 数据校验 | 支持 | 不支持 |
复杂类型 | 支持 | 不支持 |
解析:
-
SpEl 语法:指的是,可以进行简单运算
@Value("#{1+2}") private Integer age;
-
松散绑定:对待大小变量转换为配置的名称,要求上没有太严格,可多种格式:
-
Person 类属性名:firstName
-
四种格式:
- person.firstName
- person.first-name
- person.first_name
- person.FIRST_NAME
#person.firstName=123 #person.first-name=123 #person.first_name=123 #person.FIRST_NAME=123
-
数据校验
使用 @ConfigurationProperties 注解的方式注入配置,可以使用 Spring 的 @Validated 数据校验注解;
@Component
@Validated
@ConfigurationProperties(prefix = "person")
public class Person {
@Email
private String firstName;
}
实例中,@Email 注解的属性,必须是邮箱格式,否则抛出异常。
定义本地配置元数据
在类的上面加上两个注解:
- @Component
- @ConfigurationProperties
需要加载一个 jar 包依赖,之后,本地类若是需要注入的话,会有相应的提示。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
@PropertySource 与 @ImportResource
@PropertySource
加载指定的配置文件,无需从全局配置文件中获取无关 Spring 的值。
@Component
@ConfigurationProperties(prefix = "person")
@PropertySource(value = {"classpath:person.properties"})
public class Person {
// ......
}
@ImportResource
SpringBoot 默认不会加载 .xml 方式定义的 bean,若是需要以这种方式定义 bean,那么需要将其导入:
@ImportResource(locations = {"classpath: beans.xml"})
@SpringBootApplication
public class LearningApplication {
public static void main(String[] args) {
SpringApplication.run(LearningApplication.class, args);
}
}
这样,在 beans.xml 文件内定义的 bean,就会被加载到 ioc 容器中。
支持多个配置文件同时导入,locations 是一个数组类型。
定义 Bean
给 ioc 容器中注册组件,有两种方式,一种是 xml 配置文件,另外就是全注解方式。
xml 就不说了,在 SpringBoot 中,使用的很少。这种方式需要使用 @ImportResource 注解,标注在主程序类上面。
以下是 SpringBoot 全注解方式给 ioc 容器注册组件:
@SpringBootConfiguration
public class AdminConfiguration {
@Bean
public Admin admin() {
return new Admin();
}
}
可以使用 @Configuration 组件表示类是一个注解类,这是 Spring 底层支持的。
在 SpringBoot 中,可以使用 @SpringBootConfiguration 组件,这是 SpringBoot 特有的。
搭配 @Bean ,可以将一个方法的返回值作为 bean,注册到 ioc 容器中,默认的组件 id 是方法名称。
多环境支持
激活不同环境有两种方式:
- 在配置文件中:spring.profiles.active=dev
- 命令行方式:--spring.profiles.active=dev
- JVM 参数:-Dspring.profiles.active=dev
Profile 方式
SpringBoot 支持在不同环境下,使用不同的配置文件,默认的配置文件:application.properties
激活环境配置文件,在 application.properties 配置文件中指定。
格式:application-{自定义}.yml/properties
例如:application-dev.yml/properties
激活:
spring.profiles.active=dev
此时,application-dev.yml/properties 文件就生效了。
文档块方式
yaml 语法支持单个文件内,区分不同的配置区域。spring-boot 就支持这种方式。
例如:
server:
port: 8090
spring:
profiles:
active: dev
---
spring:
profiles: dev
server:
port: 8091
---
spring:
profiles: prod
server:
port: 8092
加载顺序
SpringBoot 支持不同位置,不同形式的配置文件或者参数,一共 17 种,优先级由高到低。
方式 | 描述 |
---|---|
全局配置文件 | $HOME/.config/spring-boot:这个位置配置文件适用于整个引用程序spring-boot-devtools.properties spring-boot-devtools.yaml spring-boot-devtools.yml |
@TestPropertySource | 注解标注的类 |
测试的属性 | 在@SpringBootTest和测试注释中提供,用于测试应用程序的特定部分。 |
命令行参数 | 直接对某些参数指定 |
来自 SPRING_APPLICATION_JSON(内嵌在环境变量或系统属性中的JSON)的属性 | |
ServletConfig 初始化参数 | |
ServletContext 初始化参数 | |
来自java的JNDI属性:comp/env | |
Java系统属性(System.getProperties()) | |
操作系统环境变量 | |
RandomValuePropertySource,其属性仅为:random.* | |
打包 jar 之外的特定于概要文件的应用程序属性(application-.properties和YAML变量) | profile 是不同环境使用的配置 |
打包在 jar 中的特定于概要文件的应用程序属性(application-.properties和YAML变量) | |
打包 jar 之外的应用程序属性(Application.properties和YAML变体) | |
打包在 jar 中的应用程序属性(Application.properties和YAML变体) | |
@Configuration 类上的 @PropertySource 注释 | 请注意,在刷新应用程序上下文之前,这些属性源不会添加到环境中 现在配置某些属性(如 logging.* 和 spring.main.* 等)无效,这些属性在刷新开始之前就会被读取 |
默认属性(通过设置 SpringApplication.setDefaultProperties 指定) |
方式有很多种,但是常用的就那么几种,使用 profile 配置不同环境的配置文件,还有运行时候,通过命令行参数覆盖已有参数,又或者在 jar 所在位置添加外部配置文件,最直接的在全局配置文件定义。
指定配置文件
java -jar xxx.jar --spring.config.location="/home/config/application.properties"
配置原理
- 从主程序入口,@SpringBootApplication 注解
- 其中有一个 @EnableAutoConfiguration 注解,表示启动自动配置
- @EnableAutoConfiguration 注解中,导入了其他组件:AutoConfigurationImportSelector.class
- AutoConfigurationImportSelector
- 有几个重要的方法:
- process:处理需要自动配置的组件
- getAutoConfigurationMetadata:获取自动配置元数据
- 由 AutoConfigurationMetadataLoader,使用 AppClassLoader 类加载器获取
META-INF/spring-autoconfigure-metadata.properties
内容 - 实际上就是
spring-boot-autoconfigure-*.*.*.RELEASE.jar
这个依赖
- 由 AutoConfigurationMetadataLoader,使用 AppClassLoader 类加载器获取
- getAutoConfigurationEntry:对获取的自动配置条目进行过滤,删除重复等等操作,最后以 List 数据类型返回满足条件的组件全类名
- 有几个重要的方法:
示例,以 HttpEncodingAutoConfiguration 为例:
@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(HttpProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {
//......
}
解析:
- 类必须是配置类
- 通过 @EnableConfigurationProperties(HttpProperties.class)
- 启用 HttpProperties bean 属性绑定配置值
- 之后可以通过 HttpProperties 来依赖注入,获取其中的属性值
- 这样做的好处就是,将配置 bean 与实际组件配置区分开
- @ConditionalOnWebApplication 判断是否 Web 应用
- @ConditionalOnClass 判断其中所需类是否在当前类路径下
- @ConditionalOnProperty 判断所需添加是否满足
当 @Conditional*** 等之类的注解都满足时候,当前的自动配置类才会生效,否则无效。
小结
1)SpringBoot 内置了大量的自动配置类,所以可以从里面找到可能存在我们需要的依赖
2)一个自动配置类中会注册多个组件到 IOC 容器中
3)自动配置类会从 ***Properties 相关类中获取所需要的配置值,该类的值可以从 SpringBoot 配置文件中定义。
4)自动配置类会在满足条件的时候,才会生效,否则无效
5)通过自动配置类的方式,可以灵活的注册组件,例如说逻辑代码处理等等
6)自动配置类是 SpringBoot 的主要精髓所在,若没有这样的动能,SpringBoot 所提倡的约定优先与配置则不成立
扩展
- spring-boot 使用 snakeyaml 作为解析 yaml 语法。
- SpringBoot 外部化配置
- 内置配置
Q.E.D.
Comments | 0 条评论