博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
SpringBoot_02 yml和properties配置文件的使用
阅读量:3967 次
发布时间:2019-05-24

本文共 9998 字,大约阅读时间需要 33 分钟。

yml和properties配置文件的使用


本人是个新手,写下博客用于自我复习、自我总结。

如有错误之处,请各位大佬指出。
学习资料来源于:尚硅谷


默认生成的SpringBoot项目:

主程序已经生成好了,我们只需要写我们自己的逻辑。
resources文件夹中目录结构:

  • static:保存所有的静态资源;js css images
  • templates:保存所有的横板页面;(SpringBoot默认jar包使用嵌入式的Tomcat,默认不支持jsp页面);可以使用横板引擎(freemarker,thymeleaf);
  • application.properties:SpringBoot应用的配置文件。可以修改一些默认配置。
    在这里插入图片描述
    对于配置文件,名字是固定的,application.properties或者application.yml。
    这个配置文件就是修改SpringBoot自动配置的默认值。
    yml就是YAML(YAML Ain’t Markup Language):它既是一个标记语言又不是一个标记语言。
    标记语言:以前的配置文件,大多都使用的是 xxxx.xml文件;
    YAML:以数据为中心,比json、xml等更适合做配置文件。

YAML配置实例:

server:  port: 8081

XML:

8081

也就可以发现,XML会花费大量精力在标签上。

YAML语法:

(1)基本语法:

k:(空格)v

表示一对键值对(空格必须有);

以空格的缩进来控制层级关系。只要是左对齐的一列数据都是同一个层级的。

server:  port: 8081  path: /hello

属性和值也是大小写敏感。

(2)值的写法

字面量:普通的值(数字,字符串,布尔)

k: v     字面量直接来写;字符串默认不用加上单引号或者双引号;         如果加上双引号,不会转义字符串里面的特殊字符;         特殊字符会作为本身想表示的意思         比如 name: "zhangsan \n lisi"  输出的是zhangsan 换行 lisi         而单引号会转义特殊字符,特殊字符最终只是一个普通的字符串数据         比如 name: 'zhangsan \n lisi'  输出的是 zhangsan \n lisi

对象(属性和值)(键值对):比如Map

k: v    对象还是这样的方式。在下一行来写对象的属性和值的关系;注意缩进。	    比如 friends:	              lastName: zhangsan	              age: 20	    还可以行内写法:	    friends: {lastName: zhangsan,age: 18}

数组:比如List,Set

用- 值表示数组中的一个元素。比如pets:   - cat   - dog   - pig行内写法:pets: [cat,dog,pig]

在编写好yml文件后,需要在pom.xml中导入配置文件处理器,这样绑定成功后才会有提示:

org.springframework.boot
spring-boot-configuration-processor
true

示例:

application.yml:

server:  port: 8081person:  lastName: zhangsan  age: 18  boss: false  birth: 2020/1/2  maps: {
k1: v1,k2: 12} lists: - lisi - zhaoliu dogs: name: 小狗 age: 2

Person.java:

package com.guigu.srpingboot.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;/** * 将配置文件中配置的每一个属性的值,映射到这个组件中 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定。 * prefix = "person":配置文件中哪个下面的所有属性进行一一映射 * * 只有这个组件是容器中的组件,才能使用容器提供的功能。 * */@Component@ConfigurationProperties(prefix = "person")public class Person {
private String lastName; private Integer age; private Boolean boss; private Date birth; private Map
maps; private List
lists; private Dog dog; public String getLastName() {
return lastName; } public void setLastName(String lastName) {
this.lastName = lastName; } public Integer getAge() {
return age; } public void setAge(Integer age) {
this.age = age; } public Boolean getBoss() {
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
getMaps() {
return maps; } public void setMaps(Map
maps) {
this.maps = maps; } public List
getLists() {
return lists; } public void setLists(List lists) { this.lists = lists; } public Dog getDog() { return dog; } public void setDog(Dog dog) { this.dog = dog; } @Override public String toString() { return "Person{" + "lastName='" + lastName + '\'' + ", age=" + age + ", boss=" + boss + ", birth=" + birth + ", maps=" + maps + ", lists=" + lists + ", dog=" + dog + '}'; }}

Dog.java:

package com.guigu.srpingboot.bean;public class Dog {
private String name; private Integer age; public String getName() {
return name; } public void setName(String name) {
this.name = name; } public Integer getAge() {
return age; } public void setAge(Integer age) {
this.age = age; } @Override public String toString() {
return "Dog{" + "name='" + name + '\'' + ", age=" + age + '}'; }}

之后就可以在自动生成的test文件夹中,用spring中的test来测试是否修改成功:

package com.guigu.srpingboot;import com.guigu.srpingboot.bean.Person;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.context.SpringBootTest;/** * springboot单元测试: * 可以在测试期间很方便的类似编码一样进行自动注入等容器的功能 * */@SpringBootTestclass SrpingBoot02ConfigApplicationTests {
@Autowired Person person; @Test public void contextLoads() {
System.out.println(person); }}

运行之后会发现,执行成功!

如果相同的配置对于application.properties的话配置如下:

#配置person的值person.last-name=张三person.age=18person.birth=2020/1/2person.maps.k1=v1person.maps.k2=14person.boss=falseperson.lists=a,b,cperson.dog.name=dogperson.dog.age=15

同样的,还有其他的获取值的方式,如下:

package com.guigu.srpingboot.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 {
@Value("${person.last-name}") private String lastName; @Value("#{11*2}") private Integer age; @Value("true") private Boolean boss; private Date birth; private Map
maps; private List
lists; private Dog dog; //忽略}

显然,@ConfigurationProperties和@Value区别如下:

① @Value无法实现批量注入配置文件中的属性,需要一个一个配置

② 同时:@Value("${person.last-name}")无法更改,改成@Value("${person.lastName}")就无法匹配,导致报错,即不支持松散绑定。也就是说,在person中lastName无论在yml中,名字是lastName还是last-name都会匹配成功。
③ @Value是支持SpEL的,@ConfigurationProperties不能
④ @ConfigurationProperties支持JSR303数据检验,而@Value不支持。
比如:(数据格式不对会报错,而@Value会忽略)

package com.guigu.srpingboot.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")@Validatedpublic class Person {
//lastName必须是邮箱格式 @Email private String lastName; private Integer age; private Boolean boss; private Date birth; private Map
maps; private List
lists; private Dog dog; //忽略}

⑤ @Value不支持复杂类型封装,即如下这种就不能获取,只能获取简单的。

@Value("${person.maps}")private Map
maps;

也就是说,配置文件yml和properties都能获取到值,如果说我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@value。如果说我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties

@ConfigurationProperties(prefix = “person”) 默认从全局配置文件中获取值。

但显然如果所有的信息全放在一个properties里,文件太大,不太好。

所以可以把里面的信息分出来,比如 建一个person.properties。

这时就可以使用@PropertySource(value = {“classpath:person.properties”})

这样就能绑定到类路径下的properties。

package com.guigu.srpingboot.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")@PropertySource(value = {
"classpath:person.properties"})public class Person {
//lastName必须是邮箱格式 @Email private String lastName; private Integer age; private Boolean boss; private Date birth; private Map
maps; private List
lists; private Dog dog; //忽略}

注解@ImportResource

还有一个注解@ImportResource:它可以导入Spring的配置文件,让配置文件里的内容生效。

在这里插入图片描述
建一个SpringConfig:beans.xml
再建一个HelloService.java(无需内容)

测试部分:

@Autowired    ApplicationContext ioc;    @Test    public void testHelloService() {
boolean b =ioc.containsBean("helloService"); System.out.println(b); }

通过测试,可以发现,SpringBoot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别;想让Spring的配置文件生效,就需要这个注解@ImportResource,并把它标在主配置类上。

import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;import org.springframework.context.annotation.ImportResource;@ImportResource(locations={
"classpath:beans.xml"})@SpringBootApplicationpublic class SrpingBoot02ConfigApplication {
public static void main(String[] args) {
SpringApplication.run(SrpingBoot02ConfigApplication.class, args); }}

再运行就发现,结果为true了。

全注解

但是在开发的时候,不可能给容器中加一个组件,我来写一个配置文件,再把这个配置文件导进来,这样太麻烦了。对于SpringBoot,推荐的方式是:(使用全注解的方式)

1、建一个配置类
2、使用@Bean给容器中添加组件

MyAppConfig.java

package com.guigu.srpingboot.config;import com.guigu.srpingboot.service.HelloService;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;/** * @Configuration:指明当前类是一个配置类,就是来替代之前的Spring配置文件 * * 以前,在配置文件中使用bean标签添加组件,但是在配置类中, * */@Configurationpublic class MyAppConfig {
//将方法的返回值添加到容器中,容器中这个组件默认的id就是方法名。 @Bean public HelloService helloService(){
System.out.println("配置类@Bean给容器中添加组件了..."); return new HelloService(); }}

配置文件占位符用法

接下来还有一个配置文件占位符的用法,对properties和yml都适用!

比如:

为其提供一个随机id:person.last-name=张三${random.uuid}为其提供一个随机int:person.age=${random.int}取上面提供过的一个值(因为是lastName,在Person中有定义,所以这个last-name必须有一个值才能这么写!否则会报错)person.dog.name=${person.last-name}_dog而相对的,如果不用一个特殊的值,如下,就不会报错。并且还为这个它赋了一个默认值 hello,也就是说,只要person.hello取不出值就是用默认值 hello,否则使用指定的值替代。如果不设置默认值,且没指定值,则输出person.hello:person.dog.name=${person.hello:hello}_dog

Profile:

1、多Profile文件:

我们在主配置文件编写的时候,文件名可以是 application-(profile).properties/yml 。

比如:(相当于指定一个运行环境)

application-dev.properties :

server.port=8082

application-prod.properties :

server.port=80

当你在运行时,就会发现,它默认使用application.properties的配置。而激活指定profile的方法:

application.properties :

server.port=8081spring.profiles.active=dev

在配置文件中指定 spring.profile.active=dev即可。

也就是说对于properties中,需要建立多个文件,而且需要去激活。

现在使用yml文件。

2、yml支持多文档块方式

application.yml:

server:  port: 8081spring:  profiles:    active: dev---server:  port: 8083spring:  profiles: dev---server:  port: 8084spring:  profiles: prod

用三个短横线就可以把yml文件分成多个文档块,使用哪个环境只要在第一块中指定即可。

配置文件的加载位置

springboot 启动会扫描一下位置的application.properties或者application.yml文件作为Springboot的默认配置文件:

file:./config/
file:./
classpath:/config/
classpath:/
以上是按照优先级从高到低的顺序,所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容。

除此以外,还有很多配置位置,以及外部配置加载位置,详情百度,参考spring官方文档。

转载地址:http://dayki.baihongyu.com/

你可能感兴趣的文章
20-python之切片详细介绍
查看>>
P24-c++类继承-01详细的例子演示继承的好处
查看>>
P8-c++对象和类-01默认构造函数详解
查看>>
P1-c++函数详解-01函数的默认参数
查看>>
P3-c++函数详解-03函数模板详细介绍
查看>>
P4-c++函数详解-04函数重载,函数模板和函数模板重载,编译器选择使用哪个函数版本?
查看>>
P5-c++内存模型和名称空间-01头文件相关
查看>>
P6-c++内存模型和名称空间-02存储连续性、作用域和链接性
查看>>
P9-c++对象和类-02构造函数和析构函数总结
查看>>
P10-c++对象和类-03this指针详细介绍,详细的例子演示
查看>>
Mule ESB-Content-Based Routing Tutorial(1)
查看>>
Mule ESB-Content-Based Routing Tutorial(2)
查看>>
Mule ESB-Content-Based Routing Tutorial(3)
查看>>
年末项目经验总结
查看>>
做事情要放下面子,拿起责任
查看>>
敏捷开发实践(1)-故事工作量估算导致的问题
查看>>
记一次解决jenkins持续构建,自动部署的问题
查看>>
敏捷开发实践(2)-要不要文档?
查看>>
写博意味着什么
查看>>
比较Cint() , int() , fix() ,round()的区别
查看>>