二、配置文件
1.配置文件
Spring Boot使用全局配置文件,配置文件名固定。
- application.properties
- application.yml
配置文件的作用:修改SpringBoot自动配置的默认值。
YAML(YAML Ain`t Markup Language)
以数据为中心,比json、xml等更适合做配置文件。
举例:
YAML
server:
port: 8081
XML
<server>
<port>8081</port>
</server>
2.YAML语法
1.基本语法
k: v:表示一对键值对(其中v前必须有空格)
以空格的缩进来控制层级关系。左对齐的一列数据都是同一层级。
属性和值大小写敏感。
2.值的写法
字面量:普通的值(数字、字符串、布尔值)
K: v:字面值直接写;
字符串默认不用加引号
“”:双引号不会转义字符串内特殊字符
name: “hello \n world”
(输出:
hello
world)
‘’:单引号会转义特殊字符
name: ‘hello \n world’
(输出:
hello \n world)
对象、Map:
k: v:在下一行写对象的属性和值的关系(注意缩进)
例:
friends:
name: zhangsan
age: 20
行内写法:
friends: {name: zhangsan,age: 20}
数组(List、Set):
用-值表示数组中的每个元素
例:
pets:
- cat
- dog
- pig
行内写法:
pets: [cat,dog,pig]
3.配置文件值注入
1.配置文件写法
配置文件:
person:
name: 清都山水郎
age: 20
boss: true
birth: 2000/08/20
maps: {k1: v1,k2: v2}
list:
- zhangsan
- lisi
- wangwu
- zhaoliu
dog:
name: 狗子
age: 2
javaBean
/**
* 将配置文件中的每一个属性的值映射到这个组件中
* @ConfigurationProperties:告诉properties将本类中的所有属性和配置文件中的相关配置进行绑定
* prefix = "person":配置文件中person下的属性进行一一映射
*
* 只有是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
*
*/
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Integer age;
private Boolean boss;
private Date birth;
private Map<String,Object> maps;
private List<Object> list;
private Dog dog;
导入配置文件处理器,编写配置文件时自动提示
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
使用配置文件application.properties时乱码问题:
(1)file - setting - 搜索file encoding - properties Files,选择utf-8并勾选 transparent native-to-ascii conversion - 设置完成,apply。
(2)新建一个application.properties,重新运行。
2. @Value获取值和@ConfigurationProperties获取值的比较
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个个指定 |
松散绑定 | 支持 | 不支持 |
SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
注入数据的方法选择:
只是需要在业务逻辑中获取一下配置文件中的某项值,使用@Value;专门编写了javaBean来和配置文件进行映射,通常使用@ConfigurationProperties.
3.配置文件注入值数据校验
@Component
@ConfigurationProperties(prefix = "person")
@Validated //属性需校验
public class Person {
//name属性的输入必须为邮箱格式
@Email
private String name;
private Integer age;
private Boolean boss;
private Date birth;
4.@PropertySource和@ImportResurce
@PropertySource:加载指定的配置文件。
@PropertySource(value = {"classpath:person.properties"})
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
private String name;
private Integer age;
private Boolean boss;
private Date birth;
@ImportResurce:导入Spring的配置文件,使配置文件里的内容生效。
SpringBoot里没有Spring的配置文件,也无法自动识别自己编写的配置文件,将@ImportResurce标注在配置类上可以使其生效。
@ImportResource(locations = {"classpath:beans.xml"})
Springboot推荐给容器中添加组建的方式:全注解
1.配置类-spring配置文件
2.使用@Bean给容器中添加组件
@Configuration
public class MyAppConfig {
@Bean
public HelloService helloService(){
System.out.println("配置类@Bean给容器中添加组件。")
return new HelloService();
}
}
4.配置文件占位符
1.随机数
${random.value}、${random.int}、${random.long}、${random.int(10)}、${random.int[1,10]}
2.占位符获取之前配置的值,若无,可使用:指定默认值
person.name=清都山水郎${random.uuid}
person.age=${random.int}
person.birth=2000/08/20
person.boss=true
person.list=a,b,c
person.maps.k1=v1
person.maps.k2=v2
person.dog.name=${person.none:默认值}的狗子
person.dog.age=2
5.Profile
1.多profile文件
主配置文件编写时文件名为application-{profile}.properties/yml
默认使用application.properties
2.yml支持多文档块方式
server:
port: 8081
spring:
profiles:
active: dev #指定属于哪个环境
---
server:
port: 8083
spring:
profiles: dev #开发环境
---
server:
port: 8084
spring:
profiles: prod #生产环境
3.激活指定profile
1.在配置文件中指定 spring.profiles.active=dev
2.命令行:
(1)java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev
(2)也可以直接在测试的时候,配置传入命令行参数
3.虚拟机参数:
-Dspring.profiles.active=prod
6.配置文件加载位置
SpringBoot启动会扫描以下位置的application.properties或aplication.yml文件作为Spring boot的默认配置文件。
-file:./config/
-file:./
-classpath:/config
-classpath:/
优先级由高到低,高优先级的相同配置会覆盖低优先级。
加载时,SpringBoot会从这四个位置全部加载主配置文件,不同文件的不同配置形成互补。
我们还可以通过Spring.config.location来改变默认的配置文件位置。
项目打包好后,我们可以使用命令行参数的形式启动项目时指定配置文件的新位置。指定配置文件和默认配置文件共同起作用形成互补配置。
7.外部配置加载顺序
-
命令行参数
java -jar spring-boot-02-config-02-00.1-SNAPSHOT.jar --server.port=8087 --server.context-path=/boot
多个配置用空格分开,- -配置项=值
-
来自java:comp/env的JNDI属性
-
Java系统属性
-
操作系统环境变量
-
RandomValuePropertySource配置的random.*属性。
-
由jar包外向jar包内进行寻找,优先加载带profile的的配置文件,再加载不带profile的配置。
-
@Cconfiguration注解类上的@PropertySource
-
通过SpringApplication.setDefaultProperties指定的默认属性。
参考官方文档
8.自动配置原理
1.自动配置原理:
1)SpringBoot启动的时候加载主配置类,开启了自动配置功能@EnableAutoConfiguration
2)@EnableAutoConfiguration作用:
-
利用EnableAutoConfigurationImportSelector给容器中导入一些组件
-
可用插件selectImports()方法
-
List configuration = getCandidateConfigurations(annotationMetadata,attributes); 获取候选的配置
-
SpringFactoriesLoader.loadFactoryNames()
扫描所有jar包类路径下 META-INF/spring.factories,把扫描到的这些文件的内容包装成properties对象。从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后添加进容器中。将类路径下META-INF/spring.factories里配置的所有EnableAutoConfiguration的值加入到容器中。
# Auto Configure org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\ org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\ org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\ org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\ org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\ org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\ org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\ org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\ org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\ org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\ org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\ org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\ org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\ ...
-
每一个xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中做自动配置。
3)每一个自动配置类进行自动配置功能。
4)以HttpEncodingAutoConfiguration(Http编码自动配置)为例解释自动配置原理:
@Configuration(proxyBeanMethods = false)//是一个配置类,也可以给容器中添加组件
@EnableConfigurationProperties({ServerProperties.class})
//启动指定类的ConfigurationProperties功能;将配置文件中对应的值和httpEncodingProperties绑定起来。
@ConditionalOnWebApplication //满足指定的条件时,配置类生效
@ConditionalOnClass({CharacterEncodingFilter.class})
//判断当前项目有无CharacterEncodingFilter.class类。CharacterEncodingFilter:SpringMVC中进行乱码解决的过滤器
@ConditionalOnProperty(prefix = "server.servlet.encoding", value = {"enabled"}, matchIfMissing = true)
//判断配置文件中是否存在某个配置,即使不存在,server.servlet.encoding=true也默认生效。
public class HttpEncodingAutoConfiguration {
//和springBoot的配置文件映射
private final Encoding properties;
//有参构造器,参数值从容器中获取
public HttpEncodingAutoConfiguration(ServerProperties properties) { /* compiled code */ }
@Bean //给容器中添加组件,某些值需要从preoperties中获取
@ConditionalOnMissingBean
public CharacterEncodingFilter characterEncodingFilter() { /* compiled code */ }
}
@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)//从配置文件中获取指定的值和bean的属性进行绑定
public class ServerProperties {
}
一旦一个配置类生效,配置类就会给容器添加各种组件。组件属性从对应properties类中获取。类中的每个属性和配置文件绑定。
-
SpringBoot启动会加载大量自动配置类
-
看需要的功能是否在springboot默认有写好的自动配置类
-
看自动配置类中是否有需要的组件
-
给容器中自动配置类添加组件时,从properties类中获取属性,我们在配置文件中指定这些属性的值。
xxxAutoConfiguration:自动配置类。给容器中添加组件
xxxProperties:封装配置文件中的相关属性。
2.细节
1.@Conditional派生注解
当@Conditional指定的条件成立,才给容器中添加组件,配置里的内容才生效。
@Cconditional扩展注解 | 作用 |
---|---|
@ConditionalOnJava | 系统Java版本是否符合要求 |
@ConditionalOnBean | 容器中存在指定的bean |
@ConditionalOnMissingBean | 容器不存在指定bean |
@ConditionalOnExpression | 满足SpEL指定表达式 |
@ConditionalOnClass | 系统有指定类 |
@ConditionalOnSingleCandidate | 容器中有一个指定的bean或者这个bean是首选bean |
@ConditionalOnProperty | 系统指定的属性是否有指定值 |
@ConditionalOnResource | 类路径是否存在指定资源文件 |
2.自动配置类必须在一定条件下才生效。
可以通过启用debug=true
属性,来让控制台打印自动配置报告。
============================
CONDITIONS EVALUATION REPORT
============================
Positive matches: //启用的自动配置类
-----------------
AopAutoConfiguration matched:
- @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)
AopAutoConfiguration.ClassProxyingConfiguration matched:
- @ConditionalOnMissingClass did not find unwanted class 'org.aspectj.weaver.Advice' (OnClassCondition)
- @ConditionalOnProperty (spring.aop.proxy-target-class=true) matched (OnPropertyCondition)
Negative matches: //未启用的自动配置类
-----------------
ActiveMQAutoConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)
AopAutoConfiguration.AspectJAutoProxyingConfiguration:
Did not match:
- @ConditionalOnClass did not find required class 'org.aspectj.weaver.Advice' (OnClassCondition)