配置文件
Springboot使用一个全局的配置文件,配置文件名是固定的,可以在运行jar包时使用
--spring.config.name
属性去指定名称,--spring.config.location
属性用于指定特定的配置文件路径
- applocation.properties
- application.yml
配置文件的作用:修改SpringBoot自动配置的默认值。
配置文件优先级
- 根目录下的/config目录下的配置文件
- 根目录下的配置文件
- 类路径下的/config目录下的配置文件
- 类路径下的配置文件
- 当yaml与properties同时存在时,properties文件优先级最高(springboot 2.4之前);yaml>properties 是在springBoot 2.4之后
YAML
.yml是YAML(YAML Ain’t Markup Language)语言的文件,以数据为中心,比json、xml等更适合做配置文件
YAML语法
YAML基本语法
- K:(空格)V:表示一对键值对(空格必须有);
- 以空格的缩进来控制层级关系;只要左对齐的一列数据都是同一个层级的
server:
port: 8080
path: /hello- 属性和值也是大小写敏感的。
值的写法
YAML 支持的数据结构有三种
对象:键值对的集合,又称为映射(mapping)/ 哈希(hashes) / 字典(dictionary)
数组:一组按次序排列的值,又称为序列(sequence) / 列表(list)
纯量(scalars):单个的、不可再分的值
YAML 语言教程对象
对象的一组键值对,使用冒号结构表示。
animal: pets
hash: { name: Steve, foo: bar } #行内写法
friend :
fname : haha
age : 20数组
一组连词线开头的行,构成一个数组。
- Cat
- Dog
- Goldfish
animal: [Cat, Dog] #行内写法复合结构
对象和数组可以结合使用,形成复合结构。
languages:
- Ruby
- Perl
- Python
websites:
YAML: yaml.org
Ruby: ruby-lang.org
Python: python.org
Perl: use.perl.org纯量
纯量是最基本的、不可再分的值。以下数据类型都属于 JavaScript 的纯量。
- 数值直接以字面量的形式表示。
- 布尔值用true和false表示。
- null用~表示。
- 时间采用 ISO8601 格式
iso8601: 2001-12-14t21:59:43.10-05:00
- 日期采用复合 iso8601 格式的年、月、日表示。
date: 1976-07-31
- YAML 允许使用两个感叹号,强制转换数据类型。
字符串
字符串默认不使用引号表示。
- 如果字符串之中包含空格或特殊字符,需要放在引号之中。
- 单引号和双引号都可以使用,双引号不会对特殊字符转义。
name : "zhangsan \n lisi" -> 输出 zhangsan 换行 lisi
name : 'zhangsan \n lisi' -> 输出 zhangsan \n lisi- 字符串可以写成多行,从第二行开始,必须有一个单空格缩进。换行符会被转为空格。
- 多行字符串可以使用|保留换行符,也可以使用>折叠换行。
this: |
Foo
Bar
that: >
Foo
Bar- +表示保留文字块末尾的换行,-表示删除字符串末尾的换行。
配置文件值注入
1、我们编写实体类,bean类
2、在yml文件中编写对应的配置信息
3、在要注入的类中加入以下注解- @Component:将类加载到SpringBoot容器中
- @ConfigurationProperties(prefix = “”) :将类与配置文件信息一一映射,prefix是对应的映射父对象,默认从全局配置文件中获取值
然后以注入的形式加载到我们使用的类中的时候就会带着配置文件的信息了。
yml文件
person : |
对应的javabean
/** |
导入配置文件处理器
导入配置文件处理器以后,我们再进行编写配置的时候就有提示了
<!--导入配置文件处理器,配置文件进行绑定就会有提示--> |
单元测试
单元测试必须都是pulic的方法,不然没有办法执行
要注入的javabean类必须自动注入的方式,new是不会去读配置文件的。
代码演示
/** |
== 要注意的一点就是:javabean必须有get,set方法才可以。==
使用properties文件进行配置
#idea properties文件配置成utf-8编码 |
这里需要注意的是,在proterties文件中我们使用中文的时候可能会出现乱码现象,记得把idea的配置文件编码格式设置为utf-8允许转换成ASCII码
其他不用变,properties文件的优先级比yml高,他俩获取的方式都是一样的无需改动
其他获取方式
@Value
spring中对于加载bean的时候会用到用value的方式进行读取,那么SpringBoot就是使用了这个方式
/** |
注解的区别
@ConfigurationProperties | @Value | |
---|---|---|
功能 | 批量注入配置文件中的属性 | 一个一个指定 |
松散绑定(松散语法) | 支持 | 不支持 |
支持SpEL | 不支持 | 支持 |
JSR303数据校验 | 支持 | 不支持 |
复杂类型封装 | 支持 | 不支持 |
#### JSR303数据校验使用方法 |
1、在bean类的加上注解@Validated
2、在要进行数据校验的地方加入相应的注解即可
|
松散绑定
- person.firstName:使用标准写法
- person.first-name:大写用-
- person.first_name:大写用_
- PERSON_FIRST_NAME: 系统推荐这种写法
@PropertySource&@ImportResource
@PropertySource
用于加载指定的配置文件
- 使用PropertySource时必须有ConfigurationProperties注解,不然取不到值
- PropertySource后面获取配置文件的时候必须将文件名和后缀名都写上,不然报错
"person") (prefix = |
@ImportResource
导入Spring的配置文件,让配置文件内容生效
SpringBoot中没有Spring的配置文件,我们自己编写的配置文件不能自动识别
想让Spring配置文件生效,就需要使用这个注解
在主配置类加上注解
"classpath:beans.xml"})//配置文件是自己定义的 (locations = { |
SpringBoot推荐给容器中添加组件的方式,推荐使用全注解的方式
- 配置类=======Spring配置文件
- 使用@Bean给容器中添加组件
/** |
配置文件占位符
RandomValuePropertySource:
配置文件中可以使用随机数
- ${random.int}
- ${random.value}
- ${random.long}
- ${random.int(10)}
- ${random.int[1024,65536]}
属性配置占位符
可以在配置文件中引用前面配置过的属性(优先级前面配置过的这里都能用)
${app.name:默认值}来指定找不到属性时的默认值
zhangsan = |
Profile
Profile是Spring对不同环境提供不同配置功能的支持,可以通过激活、指定参数等方式快速切换环境
多Profile文件
我们在主配置文件编写的时候,文件名可以是application-{profile}-properties/yml
默认使用application。properties作为配置文件
yml多文档块
server: |
激活支持Profile
- 在配置文件中指定spring.profiles.active= dev 来激活
- 命令行来激活 –spring.profiles.active = dev
- 在IDEA中进行编写
- 打包称为jar包运行的时候编写
- 利用jvm参数 -Dspring.profilers.active=dev
配置文件加载位置
SpringBoot启动扫描以下位置的application.properties或者时application.yml文件作为SpringBooy的默认配置文件
- file:./config/
- file:./
- classpath:/config/
- classpath:/
以上是按照优先级从高到低地顺序,所有位置地文件都会被加载,高优先级配置内容会覆盖低优先级配置地内容
我们也可以通过配置spring.config.location来改变默认配置- 项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候指定配置文件的新位置
- 指定配置文件和默认加载的配置文件一起被启动,形成互补配置。
高低优先级会形成互补配置,也就是说高优先级没有地配置在低优先级存在不会被覆盖。
SpringBoot支持多种外部配置方式
springBoot可以从以下位置读,下面是顺序是优先级
- 命令行参数(多个配置按照空格分开)
- 来自java:comp/env的JNDI属性
- java系统属性(System.getProperties)
- 操作系统环境变量
- RandomValuePropertySource配置的random.*属性
- jar包外部的application-{profile}.properties或者application.yml(带spring.profile配置文件)
- jar内部的application-{profile}.properties或者application.yml(带spring.profile配置文件)
- jar外部的application-{profile}.properties或者application.yml(不带spring.profile配置文件)
- jar内部的application-{profile}.properties或者application.yml(不带spring.profile配置文件)
- @Configuration注解类上的@PropertySource
- 通过SpringApplication.setDefaultPerties指定的默认属性
自动配置原理
所有配置文件用到的配置可以在这里找到通用应用程序属性
1、SpringBoot启动的时候加载主配置类,开启自动配置功能 ==@EnableAutoConfiguration==
- EnableAutoConfiguration作用就是利用AutoConfigurationImportSelector的selectImports进行自动装配
- selectImports里面对选择的配置进行装配:List
configurations = getCandidateConfigurations(annotationMetadata,attributes);这句话就是获取候选的配置然后以configurations的形式返回
- List
configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
作用是扫描所有jar类路径下的META-INF/Spring.factories,把扫描到的文件内容包装成properties对象,从prpperties中获取到EnableAutoConfiguration.class类(类名)对应的值,把他们添加到容器- ==EnableAutoConfiguration就是将类路径下META-INF/spring.factories里面配置的所有EnableAutoConfiguration的值加入到容器中==
每一个这样的xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中;用他们来做自动配置
2、每一个自动配置类进行自动配置功能
3、 以HttpEncodingAutoConfiguration为例解释自动配置功能
//表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件 |
所有在配置文件能配置的属性都是在xxxProperties类中封装这;配置文件中能配置什么就可以参照某个功能对应的这个属性类
"spring.http.encoding") //从配置文件中获取指定的值和bean的属性进行绑定 (prefix = |
对应的properties里面的属性
#我们能配置的属性都是来源于这个功能的 |
- @Configuration //表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件
- @EnableConfigurationProperties(HttpEncodingProperties.class) //启用指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来了
- HttpEncodingProperties类里面实现的ConfigurationProperties注解,直接解析spring.http.encoding配置
- @ConditionalOnWebApplication //spring底层有一个@Conditional注解。作用是根据不同的条件,如果满足指定的条件,那么整个配置类里面的配置就会生效,这个注解的意思是判断这个应哟共是否是web应用,如果是那么当前配置类生效
- @ConditionalOnClass(CharacterEncodingFilter.class)//判断当前项目由没有CharacterEncodingFilter这个类,这个类是Springmvc中解决乱码问题的拦截器
- @ConditionalOnProperty(prefix = “spring.http.encoding”, value = “enabled”, matchIfMissing = true)//判断配置文件中国是否存在某个配置,spring.http.encoding,matchIfMissing如果不存在,判断也是成立的,即使我们配置文件不配置spring.http.encoding= true 也能默认生效
- @Bean//给容器中添加一个组件,这个组件的某些值需要从properties中获取
根据当前不同的条件判断,决定这个配置类是否生效,一旦这个配置类生效,这话配置类就会给容器中添加各种组件,这些组件的属性都是从对应的properties中获取的,这些类里面的每个属性又是和配置文件绑定的
Springboot精髓:
- SpringBoot启动会加载大量的自动配置类
- 我们看我们需要的功能有没有SpringBoot默认写好的自动配置类
- 我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,那么我们就不需要再来配置了)
- 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性,我们就可以在配置文件中指定这些属性的值
XXXAutoConfigurartion:自动配置类;
给容器中添加组件;
XXXProperties:封装配置文件中的相关属性;
一些细节
- @Conditional派生注解(Spring中有这个注解,属于原生Spring的注解)
- 作用:必须是@Conditional指定的条件才能成立,才能给容器中添加组件,配置里面的所有内容才能生效;
- SpringBoot中对这个注解做了很多扩展,
@Conditional扩展注解 | 作用(判断是否满足当前指定条件) |
---|---|
@ConditionalOnJava | 系统的java版本是否符合要求 |
@ConditionalOnBean | 容器中存在指定Bean; |
@ConditionalOnMissingBean | 容器中不存在指定Bean; |
@ConditionalOnExpression | 满足SpEL表达式指定 |
@ConditionalOnClass | 系统中有指定的类 |
@ConditionalOnMissingClass | 系统中没有指定的类 |
@ConditionalOnSingleCandidate | 容器中只有一个指定的Bean,或者这个Bean是首选Bean |
@ConditionalOnProperty | 系统中指定的属性是否有指定的值 |
@ConditionalOnResource | 类路径下是否存在指定资源文件 |
@ConditionalOnWebApplication | 当前是web环境 |
@ConditionalOnNotWebApplication | 当前不是web环境 |
@ConditionalOnJndi | JNDI存在指定项 |
自动配置类一般在一定条件下才能生效;
我们怎么知道哪些自动配置类生效;
我们可以通过在配置文件中启用 debug=true属性;来让控制台打印自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效;