Spring Boot(二)—— 配置文件

二、Spring Boot配置文件

1. 配置文件

Spring Boot使用一个全局配置文件,配置文件名固定

  • application.properties

  • application.yml

配置文件存放路径

  • 配置文件是放在src/main/resources目录或者类路径/config下

配置文件作用

  • .yml是YAML语言的文件,以数据为中心,比json,xml等更适合做配置文件

  • 参考语法规范

  • 全局配置文件可以对一些默认配置值进行修改

YAML配置端口号:

server:
port: 8081

XML:

<server>
<port>8081</port>
</server>

2. YAML语法

基本语法

  • Key: Vaule: 表示键值对,key:和Vaule:后有空格

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

  • 属性和值的大小写敏感

值的写法

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

    K:V:字面直接来写,字符串默认不用加引号

    加上“”:不会转义特殊字符,特殊字符会作为本身想表示的意思

    加上‘’:会转义特殊字符,如‘\n’会展示位字符串

  • 对象、Map(属性和值)(键值对)

    K:V:在下一行写队形的属性和值的关系,注意缩进

    对象还是k: v: 的方式

    friends:
    name: 张三
    age:20

    行内写法:

    friends:{name: 张三,age: 20}
  • 数组(List、Set)

    - 值表示数组中的一个元素

    pets:
    - cat
    - dog
    - pig

    行内写法

    pets: [cat,dog,pig]

3. 配置文件值注入

3.1 创建Person类和Dog类

编写类中属性,setter & getter方法和toString()方法

Persong.java

public class Person {
   private String lastName;
   private Integer age;
   private boolean boos;
   private Date birth;

   private Map<String,Object> maps;
   private List<Object> 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 isBoos() {
       return boos;
  }

   public void setBoos(boolean boos) {
       this.boos = boos;
  }

   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;
  }

   @Override
   public String toString() {
       return "Person{" +
               "lastName='" + lastName + '\'' +
               ", age=" + age +
               ", boos=" + boos +
               ", birth=" + birth +
               ", maps=" + maps +
               ", lists=" + lists +
               ", dog=" + dog +
               '}';
  }
}

Dog.java

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 +
               '}';
  }
}

3.2 配置属性文件

3.2.1 YAML属性文件配置
person:
lastName: zhangsan
age: 18
boss: false
birth: 2017/12/12
maps: {k1: v1,k2: v2}
lists:
  - lisi
  - zhaoliu
dog:
  name: 小狗
  age: 2
3.2.2 properties属性文件配置
person.last-name=张三
person.age=18
person.birth=2017/12/15
person.boos=false
person.maps.k1=v1
person.maps.k2=v2
person.lists=a,b,c
person.dog.name=dog
person.dog.age=15

注意:

  • properties中文显示可能会出现乱码

  • image-20201209114951477

  • 解决办法:

  • image-20201209115359835

 

3.3 获取属性文件的值

在Persong类上添加:

  • @Component

  • @configurationProperties(prefix = “person”)

@ConfigurationProperties(prefix = "person")

  • 告诉Spring Boot将本类中的所有属性和配置文件中相关配置进行绑定

  • prefix = “person”:配置文件中哪个下面的所有属性进行一一映射

  • 添加这个注释可能会报出警告,此时添加下面依赖,并重新运行项目

    <!--        导入配置文件处理器,配置文件进行绑定就会有提示-->
           <dependency>
               <groupId>org.springframework.boot</groupId>
               <artifactId>spring-boot-configuration-processor</artifactId>
               <optional>true</optional>
           </dependency>

@Component

  • 只有这个组件是容器中的组件,才能提供@ConfigurationProperties(prefix = "person")功能,故加上@Component

3.4 测试

  • image-20201209113228920

  • 在SpringBoot02ConfigApplicationTests中进行测试

  • Spring Boot单元测试,可以在测试期间很方便的类似编码一样自动注入的容的功能

3.5. @value获取值和@ConfurationProperties区别

使用@Value获取值

  • 加载配置文件的值

    @Value("${person.last-name}")
    private String lastName;
  • @Value还可以直接写入值,不需要加载配置文件

    @Value("12")
    private Integer age;

@value获取值和@ConfurationProperties比较

 @ConfigurationProperties@Value
功能 批量注入配置文件中的属性 一个个指定
松散绑定(松散语法) 支持 不支持
SpEL 不支持 支持
JSR303数据校验 支持 不支持
复杂类型封装 支持 不支持

配置文件yml还是properties他们都能获取到值;

如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;

如果说,我们专门编写了一个javaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;

3.6 配置文件注入值数据校验

pom.xml文件添加以下依赖:

<!--        数据校验依赖-->
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-validation</artifactId>
       </dependency>

Person类通过配置文件注入值时只能用@ConfigurationProperties,并且添加@Validated注解

@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
   /**
    * <bean class="Person">
    *     <property name="laseName" value="字面量/${key}从环境变量、配置文件中获取值/#{spEL}“></property>
    * </bean>
    */
//   @Value("${person.last-name}")
   @Email
   private String lastName;

@RestController@ResponseBody@Controller的结合,用于返回jison数据

3.7. @PropertiesSource、@ImportResource和@Bean

3.7.1 @ProperttySource
  • 加载指定的配置文件

  • @ConfigurationProperties:默认从全局配置文件中获取值,数据多时,会造成难以处理

  • package com.why.springboot.bean;

    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.stereotype.Component;
    import org.springframework.validation.annotation.Validated;

    import javax.validation.constraints.Email;
    import java.util.Date;
    import java.util.List;
    import java.util.Map;

    /**
    * @Description TODO 将配置文件中配置的值映射到Person中
    * @ConfigurationProperties: 告诉Spring Boot将本类中的所有属性和配置文件中相关的配置进行绑定
    * prefix = "person": 配置文件中那个下面的所有属性进行一一映射
    * 只有这个组件是容器中的组件,才能提供@ConfigurationProperties(prefix = "person")功能,故加上@Component
    * @Author why
    * @Date 2020/12/9 10:53
    * Version 1.0
    **/
    @Component
    @ConfigurationProperties(prefix = "person")
    @Validated
    @PropertySource(value = {"classpath:person.properties"})
    public class Person {
       /**
        * <bean class="Person">
        *     <property name="laseName" value="字面量/${key}从环境变量、配置文件中获取值/#{spEL}“></property>
        * </bean>
        */
    //   @Value("${person.last-name}")
    //   @Email
       private String lastName;
    //   @Value("12")
       private Integer age;
       private boolean boos;
       private Date birth;

       private Map<String,Object> maps;
       private List<Object> 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 isBoos() {
           return boos;
      }

       public void setBoos(boolean boos) {
           this.boos = boos;
      }

       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;
      }

       @Override
       public String toString() {
           return "Person{" +
                   "lastName='" + lastName + '\'' +
                   ", age=" + age +
                   ", boos=" + boos +
                   ", birth=" + birth +
                   ", maps=" + maps +
                   ", lists=" + lists +
                   ", dog=" + dog +
                   '}';
      }
    }
  • 其value值还可作为数组,传入多个配置文件

3.7.2 @ImportResource
  • 作用:导入Spring的配置文件,让配置文件里面的内容生效

  • Spring Boot里面没有Spring的配置文件,我们自己编写的配置文件,也不能自动识别

    自己的配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
       <!-- 自定义Bean -->

       <bean id="helloService" class="com.why.springboot.service.HelloService"></bean>
    </beans>
  • 想让Spring的配置文件生效,加载进来,需让@ImportSource标注在一个配置类上

  • //导入Spring配置文件让其生效
    @ImportResource(locations = {"classpath:beans.xml"})

    此时Spring配置文件可用

SpringBoot推荐给容器中添加组件的方式,推荐使用全注解

  1. 配置类@Configuration - - - - - - >Spring配置文件

  2. 使用@Bean给容器中添加组件

  3. @Configuration //指明当前类是配置类,替代之前Spring的配置文件
    public class MyAppConfig {

       @Bean
       public HelloService helloService(){
           System.out.println("配置类@Bean给容器中添加组件");
           return new HelloService();
      }
    }
  4. @Configuration:指明当前类是配置类,替代之前的Spring配置文件

  5. @Bean:原来在配置文件中使用bean标签添加组件,现在使用@Bean将方法的返回值添加到容器中,容器默认的id就是方法名

3.8 配置文件占位符

3.8.1 随机数
astName: 张三${random.uuid}
age: ${random.int}
3.8.2 占位符
  1. 获取之前配置的值

  2. 如果之前没有配置也可以设置默认值

person:
lastName: 张三${random.uuid}
age: ${random.int}
boss: false
birth: 2017/12/12
maps: {k1: v1,k2: v2}
lists:
  - lisi
  - zhaoliu
dog:
  name: ${person.hello:hello}_dog
  age: 2

4. Profile多环境支持

Profile是Spring对不同环境提供不同功能的支持,可以通过激活、指定参数等方式形成快速切换环境

多Profile文件

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

例如此时创建application-dev.properties和application-prod.properties两个配置文件

默认使用application.properties

此时若激活哪个配置文件则使用那个配置文件

application-dev.properties

#开发环境下的配置文件
server.port=8081

application-prod.properties

#生产环境下的住配置文件
server.port=8082

YAML支持多文档块方式

server:
port: 8081
spring:
profiles:
  active: prod


---
server:
port: 8082
spring:
config:
  activate:
    on-profile: dev
     
---
server:
port: 8083
spring:
config:
  activate:
    on-profile: prod

激活指定的profile

  • 在application.properties文件中指定激活的配置文件

    spring.profiles.active=dev
  • YAML文档激活时使用

    spring:
    profiles:
      active: prod
  • 命令行方式激活

    - - spring.profiles.active=dev

    image-20201210163927916

    image-20201210163837534

    也可以将项目打包后运行jar文件,使用命令行形式修改激活环境

  • 虚拟机参数;

    -Dspring.profiles.active=dev

    image-20201210164556485

5. Spring Boot配置文件加载位置

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

–file:./config/

–file:./

–classpath:/config/

–classpath:/

优先级由高到低,高优先级的配置会覆盖低优先级的配置

Spring Boot会从这四个位置全部加载配置文件,最终会形成互补配置的效果

我们还可以通过spring.config.location来改变默认的配置文件位置

项目打包好以后可以使用命令行参数的形式,启动项目的时候指定配置文件的新位置。指定配置文件和默认加载的这些配置文件会共同起作用,形成互补配置

spring.config.location=文件路径

6. 外部配置加载顺序

SpringBoot也可以从以下位置加载配置; 优先级从高到低;高优先级的配置覆盖低优先级的配置,所有的配置会形成互补配置

1.命令行参数

所有的配置都可以在命令行上进行指定

java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --server.port=8087  --server.context-path=/abc

多个配置用空格分开; --配置项=值

 

2.来自java:comp/env的JNDI属性

3.Java系统属性(System.getProperties())

4.操作系统环境变量

5.RandomValuePropertySource配置的random.*属性值

 

由jar包外向jar包内进行寻找;

优先加载带profile

6.jar包外部的application-{profile}.properties或application.yml(带spring.profile)配置文件

7.jar包内部的application-{profile}.properties或application.yml(带spring.profile)配置文件

 

再来加载不带profile

8.jar包外部的application.properties或application.yml(不带spring.profile)配置文件

9.jar包内部的application.properties或application.yml(不带spring.profile)配置文件

 

10.@Configuration注解类上的@PropertySource

11.通过SpringApplication.setDefaultProperties指定的默认属性

所有支持的配置加载来源;

l参考官方文档

posted @   笔落惊风  阅读(237)  评论(0编辑  收藏  举报
编辑推荐:
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
· 软件产品开发中常见的10个问题及处理方法
· .NET 原生驾驭 AI 新基建实战系列:向量数据库的应用与畅想
阅读排行:
· 2025成都.NET开发者Connect圆满结束
· Ollama本地部署大模型总结
· langchain0.3教程:从0到1打造一个智能聊天机器人
· 用一种新的分类方法梳理设计模式的脉络
· 在 VS Code 中,一键安装 MCP Server!
点击右上角即可分享
微信分享提示