配置文件
- SpringBoot使用一个全局的配置文件,配置文件名是固定的
- application.properties
- application.yml 【需要自己创建】
- YAML(YAML Ain't Markup Language):以数据为中心,比json、xml等更适合做配置文件
- 标记语言:
- 以前的配置文件,大多都使用的是 xxxx.xml文件
- 配置文件的作用:修改SpringBoot自动配置的默认值,SpringBoot在底层都给我们自动配置好
YAML语法
- 基本语法
- k:(空格)v:表示一对键值对(空格必须有)
- 以空格的缩进来控制层级关系,只要左对齐的一列数据都是同一层级的
- 属性和值也是大小写敏感
- 值的写法
- 字面量:普通的值(数字,字符串,布尔)
- k: v:字面值直接写【字符串默认不加单引号或者双引号】
- ""双引号:不会转义字符串里面的特殊字符,特殊字符会作为本身想表示的意思
- name: "zhangsan \n lisi",输出:zhangsan 换行 lisi
- ''单引号:会转义特殊字符,特殊字符最终只是一个普通的字符串数据
- name: 'zhangsan \n lisi',输出:zhangsan \n lisi
- 对象、Map(属性和值)(键值对)
- k: v:在下一行来写对象的属性和值的关系,注意缩进
- 对象还是k: v的方式
- 行内写法:
- 数组(List、Set)
- 用- 值表示数组的一个元素
- 行内写法:
配置文件值注入
- 配置文件:
- JavaBean:
- 我们可以导入配置文件处理器,以后编写配置就有提示了
<!--导入配置文件处理器,配置文件进行绑定就会有提示--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>
properties配置文件在idea中默认utf-8可能会乱码
在 application.properties 进行配置
运行得到的lastName是乱码
进入设置,搜索File Encodings
再次运行
@Value获取值
@Value获取值和@ConfigurationProperties获取值比
- @ConfigurationProperties(prefix = "person"):默认从全局配置文件中获取值
@ConfigurationProperties @Value 功能 批量注入配置文件中的属性 一个个指定 松散绑定(松散语法) 支持 不支持 SpEL 不支持 支持 JSR303数据校验 支持 不支持 复杂类型封装 支持 不支持(只能取基本数据类型) - 注意:JSR303数据校验
- 总结:
配置文件yml还是properties他们都能获取到值
如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value
如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties
@PropertySource&@ImportResource&@Bean
@PropertySource:加载指定的配置文件
@ImportResource:导入Spring的配置文件,让配置文件里面的内容生效
Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件(xxx.xml),也不能自动识别
如果想让Spring的配置文件生效,加载进来,则需要@ImportResource标注在一个配置类上
SpringBoot推荐给容器中添加组件的方式,推荐使用全注解的方式
配置类@Configuration------>Spring配置文件
使用@Bean给容器中添加组件【如果下面代码的方法名不为helloService那么就没有添加成功】
配置文件占位符
随机数
${random.value}、${random.int}、${random.long}、${random.int(10)}、${random.int[1024,65536]}
占位符获取之前配置的值,如果没有可以是用:指定默认值
下图中:person.hello:hello ,表示如果没有person.hello那么默认是hello,如果没有后边那个hello则显示${person.hello}_dog
Profile
介绍:
Profile是Spring对不同环境提供不同配置功能的支持,可以通过激活、指定参数等方式快速切换
多Profile文件
我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml
创建多个properties文件时,默认使用的是application.properties
yml支持多文档块方式
激活指定profile
方式1:
创建多个properties文件,需要用哪个则需要在application.properties中写一行代码
方式2:
java -jar 对应程序的jar包 --spring.profiles.active=dev
可以直接在测试的时候,配置传入命令行参数【--spring.profiles.active=dev】
方式3:
虚拟机参数【-Dspring.profiles.active=dev 】
配置文件加载位置
- springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件
- 以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容。
- 例子:
- 根据上述,红框的properties的优先级最高,然后是绿框,然后是黄框
- 红框表示:-file:./
- 绿框表示:-classpath:/config/
- 黄框表示:-classpath:/
- 我们也可以通过配置spring.config.location来改变默认配置
- 方式一:这种指定配置文件路径的方式是不对的
- 在本地路径下配置一个properties,然后在代码中的properties引用本地路径下的properties
- 方式二:使用运维的方式
- 项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置,指定配置文件和默认加载的这些配置文件共同起作用形成互补配置
- java -jar jar包 --spring.config.location=G:/application.properties
外部配置加载顺序
- SpringBoot也可以从以下位置加载配置,优先级从高到低,高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置
- 命令行参数
- 所有的配置都可以在命令行上进行指定
- java -jar jar包 --server.port=8087 --server.context-path=/abc
- 多个配置用空格分开, --配置项=值
- 来自java:comp/env的JNDI属性
- Java系统属性(System.getProperties())
- 操作系统环境变量
- RandomValuePropertySource配置的random.*属性值
- 由jar包外向jar包内进行寻找
- 优先加载带profile
- jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
- jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
- 再来加载不带profile
- jar包外部的application.properties或application.yml(不带spring.profile)配置文件
- jar包内部的application.properties或application.yml(不带spring.profile)配置文件
- @Configuration注解类上的@PropertySource
- 通过SpringApplication.setDefaultProp
- 参考官方文档:外部配置加载顺序
自动配置原理
- 装配文件能配置的属性:属性参照链接
- 自动装配原理:SpringBoot自动装配原理详解
- 精髓:
- SpringBoot启动会加载大量的自动配置类
- 我们看我们需要的功能有没有SpringBoot默认写好的自动配置类
- 我们再来看这个自动配置类中到底配置了哪些组件;(只要我们要用的组件有,我们就不需要再来配置了)
- 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们就可以在配置文件中指定这些属性的值
- ***AutoConfigurartion:自动配置类
- 给容器添加组件
- ***Properties:封装配置文件中的相关属性
细节
@Conditional派生注解
作用:必须是@Conditional指定的条件成立,才给容器中添加组件,配置配里面的所有内容才生效
@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属性;来让控制台打印自动配置报告==,这样我们就可以很方便的知道哪些自动配置类生效
- 之后再运行程序,控制台就会将用到的配置类进行打印