是一种用于配置文件的标记语言
以前的配置文件一般用xml,而YAML以数据为中心(没有那么多开闭标签)
语法
key:value表示一个键值对,冒号和value之间必须有空格
以空格控制缩进来控制层级关系(那么只要左对齐就是同级)
区分大小写
value的书写
普通变量:Key: value
双引号,不会转义特殊字符。\n表示回车单引号,会转义,\n是普通字符串对象:用缩进写属性
缩进写法
行内写法
数组:用-表示一个元素
缩进写法
行内写法 Pets: [cat,dog,pig]
PS:写的时候可以注意下面的提示
new java class: bean.Person
new Java class :Dog
定义Person类和Dog类【Alt+insert键,可以一键导入get/set/toString方法】
在pom里面导入配置文件处理器的依赖项(不然会not found错误)
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency>写好person的配置文件application.yml
把配置文件的值绑定到java类中
person类前面加入:@ConfiguationProperties(perfix="person")
——告诉springboot,本类所有的属性都是由配置文件确定
——perfix,确定将配置文件中哪个属性进行一一映射
在person类前面加上@Component
——因为还要是组件内的容器,才能使用容器提供的ConfiguationProperties
在测试单元里面,注入person,看测试容器收到的person是不是配置文件设置的
这里本来应该是@Autowired,但是出现错误。修改成@Autowired(required=false)解决。
运行contextLoads()函数,控制台打印出person的信息如下:
可见,与配置文件的设置相同。
附代码:
Person.java
package com.atguigu.springboot02config.bean; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.stereotype.Component; import java.util.Date; import java.util.List; import java.util.Map; @Component @ConfigurationProperties(prefix = "person") public class Person { private String lastName; private Integer age; private boolean boss; private Date birth; private Map<String,Object> maps; private List<Object> lists; private Dog dog; @Override public String toString() { return "person{" + "lastName='" + lastName + '\'' + ", age=" + age + ", boss=" + boss + ", birth=" + birth + ", maps=" + maps + ", lists=" + lists + ", dog=" + dog + '}'; } public String getLastName() { return lastName; } public void setLastName(String lastName) { this.lastName = lastName; } public boolean isBoss() { return boss; } public void setBoss(boolean boss) { this.boss = boss; } public Date getBirth() { return birth; } public void setBirth(Date birth) { this.birth = birth; } public Map<String, Object> getMaps() { return maps; } public void setMaps(Map<String, Object> maps) { this.maps = maps; } public List<Object> getLists() { return lists; } public void setLists(List<Object> lists) { this.lists = lists; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } }Dog.java
package com.atguigu.springboot02config.bean; public class Dog { private String Name; private Integer age; @Override public String toString() { return "Dog{" + "Name='" + Name + '\'' + ", age=" + age + '}'; } public String getName() { return Name; } public void setName(String name) { Name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } }application.yml
person: lastName: zhangsan age: 90 boss: false birth: 2020/10/1 maps: {k1: v1,k2: v2} lists: - lisi - zhaoliu dog: name: wawa age: 2SpringBoot02ConfigApplicationTests.java
package com.atguigu.springboot02config; import com.atguigu.springboot02config.bean.Person; import org.junit.jupiter.api.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import java.awt.*; @RunWith(SpringRunner.class) @SpringBootTest class SpringBoot02ConfigApplicationTests<person> { @Autowired(required = false) Person person; @Test void contextLoads() { System.out.println(person); } }在application.properties里写入:
person.last-name=xxx person.age=18 person.birth=2017/10/10 person.boss=false person.maps.k1=v1 person.k2=14 person.lists=a,b,c person.dog.name=doggie person.dog.age=1设置好后,同样运行contextLoads()函数,也可以得到正确的person
但是会有中文乱码问题,解决方法:
在idea-setting-搜索file encoding-下方选择UTF-8-勾选Transparent …选项
随机数的写法: person.last-name=kris${random.uuid} person.age=${random.int} 为变量设置默认值: person.dog.name=${person.hello:hello}_dog${person.hello:hello}_dog:如果没有设置过person.hello这个东西,就会原样打印:{person.hello}_dog
${person.hello:hello}_dog:没有设置过person.hello这个东西,person.hello就会变成默认值hello,总体打印成hello_dog
之前的yml和properties都是用了@ConfiguationProperties注解,而除此之外还可以使用@Value注解
如:
@Component public class Person{ @Value("${person.last-name}") private String lastName; @Value("#{11*2}") private Integer age; }得到age=22
二者区别如下:
@ConfiguationProperties@Value注入批量设置变量值一个个指定松散绑定√×spEL×(不可计算)√JSR303数据校验√×复杂类型(如map)√√ 松散绑定:就是支持下面几种写法意义一样 spEL(就是能不能计算) JSR303数据校验:指可以加上一个@Validated表示要校验某个变量的格式,如@Email表示某个变量必须是邮箱格式,格式错误就会报错刚刚都是加载全局配置文件application.properties,现在想加载别的文件来当配置文件
方法1:
在resources文件夹-新建文件person.properties用@PropertySource(value={classpath:person.properties}):加载指定配置文件更推荐的方法(全注解方法):
添加配置类:在com下,new java class- config.MyAppConfig@Configuration 表明当前类是配置类,相当于配置文件@Bean 将方法的返回值添加到容器中这是使用配置类给容器添加组件(将方法的返回值添加到容器中),在容器中标识组件的默认id是方法的方法名(helloService)
测试容器中有没有“helloService”这个组件
在生产、开发、测试不同环境下,可能需要不同的配置文件来实现不同的配置
而主程序默认使用的是application.properties的配置
实现方法1:
在resources文件夹新建application-pro.properties(pro环境模拟),application-dev.properties(dev环境模拟),application-test.properties(test环境模拟)
(注意:格式得是application-xxx.properties或者application-xxx.yml)
在全局配置application.properties头上写spring.profiles.active=dev,指定哪个环境被激活
实现方法2(文档块方式):
在application.yml ,用---表示分割,上面叫document1,下面是document2,同理分割多个指定spring.profiles.active=dev,如以下代码,运行的就是dev环境的端口,否则默认8081 server: port: 8081 spring: profiles: active: dev --- server: port: 8083 spring: profiles: dev --- server: port: 8084 spring: profiles: prospringboot会识别以下四个位置的配置文件,而且是按优先级高到低依次往下
file指项目的根目录classpath指的是类路径,这里是main-resources识别的时候会覆盖+互补配置
覆盖:高优先级和低优先级都有,只采用高优先级的(但是也会加载低的)互补配置:指如果在高优先级没有配置的话会采用低优先级的配置项目打包好以后启动时,可以使用命令行参数的形式来指定配置文件的新位置,这时候指定的配置文件和默认加载的配置文件共同起作用形成互补配置;
——用于运维,已经打包好了不需要重新打包
配置还可以写在这17个位置,同理也有“优先级顺序+覆盖+互补”
其中较为重要的有:
命令行形式直接修改配置:
多个参数之间用空格隔开,如–server=… --path=…
来自java:comp/env的JNDI属性
Java系统属性(System.getProperties())
操作系统环境变量
RandomValuePropertySource配置的random.*属性值
【由jar包外向jar包内进行寻找; 优先加载带profile,再来加载不带profile】
jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件
jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件
jar包外部的application.properties或application.yml(不带spring.profile)配置文件
jar包内部的application.properties或application.yml(不带spring.profile)配置文件
@Configuration注解类上的@PropertySource
通过SpringApplication.setDefaultProperties指定的默认属性 所有支持的配置加载来源;
有些组件需要设置成在特定条件下生效。 @Conditional这个组件为配置的生效设置了条件,如下表:
那怎么更方便的知道哪些配置生效?
在application.properties写上debug=true
控制台打印信息中,Positive matches 表示生效的,Negetive matches表示没有生效的