首页 > 其他分享 >SpringBoot 1x 系列之(二)SpringBoot 配置

SpringBoot 1x 系列之(二)SpringBoot 配置

时间:2024-02-28 10:13:43浏览次数:26  
标签:系列 SpringBoot 配置文件 1x 配置 application properties 加载

SpringBoot 配置

配置文件、加载顺序、配置原理

1. 配置文件

SpringBoot 默认使用两种类型的配置文件作为一个全局配置文件,配置文件名固定,用于修改SpringBoot自动配置的默认值

  • application.properties
  • application.y(a)ml

1.1 YAML简介

YAML(YAML Ain't Markup Language)递归缩写

  • YAML A Markup Language:是一个标记语言;
  • YAML isn't Markup Language:不是一个标记语言;

YAML 的意思其实是:"Yet Another Markup Language"(仍是一种标记语言)。

YAML:以数据为中心,比json、xml等更适合做配置文件

XML

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

YAML

server:
  port: 8081

YAML与XML、json相比,没有像XML中大量冗余的格式标签,以数据为中心

1.2 YAML语法

1.2.1 基本语法

  1. 键值对的写法:
    在这里插入图片描述
  2. 以空格的缩进【缩进不允许使用tab,只允许空格】来控制层级关系,空格的多少没有要求,只要物理位置上处于同一列,那就是同一层级
    在这里插入图片描述
  3. 属性和值大小写敏感
    在这里插入图片描述
  4. '#'表示注释

1.2.2 值的写法

在这里插入图片描述

1.2.2.1 值为字面量

范围:数字、字符串、日期、布尔

写法:直接写
注:字符串不用加上单引号或双引号,单引号或双引号的字符串有特殊含义

  1. 双引号包围的字符串:"",不会转义字符串里面的特殊字符
    举例:"a \n b" 实际含义 "a 换行 b"
  2. 单引号包围的字符串:'',会转义字符串里面的特殊字符
    举例:"a \n b" 实际含义 "a \n b"
1.2.2.2 值为对象、Map

写法一:在下一行写对象的属性和值的关系
在这里插入图片描述
写法二:行内写法
在这里插入图片描述

1.2.2.3 值为数组

范围:List、Set、Array

写法一:用- 值表示数组中的一个元素
在这里插入图片描述
写法二:行内写法
在这里插入图片描述

1.3 JavaBean中注入配置文件的值

1.3.1 y(a)ml配置文件

JavaBean

/**
 * 将配置文件中配置的每一个属性的值,映射到这个组件中
 * @ConfigurationProperties(prefix = "person"):告诉SpringBoot将本类中的所有属性和配置文件中前缀为person的配置进行绑定,默认从全局配置文件中获取值。
 * @Component:只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能
 */

@Component
@ConfigurationProperties(prefix = "person")
public class Person {

    private String lastName;
    private Integer age;
    private Boolean boos;
    private Date birthday;

    private Map<String, Object> maps;
    private List<Object> lists;
    private Dog dog;

注:IDEA中Alt+Insert快捷生成get、set、toString方法
在这里插入图片描述

为了编写配置文件时有提示功能,可以导入SpringBoot配置文件处理器。
pom.xml

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
 	<build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <!--由于spring-boot-configuration-processor仅仅是用于提高开发体验的,在项目打包的时候不需要将这个工具打进去-->
                    <excludes>
                        <exclude>
                            <groupId>org.springframework.boot</groupId>
                            <artifactId>spring-boot-configuration-processor</artifactId>
                        </exclude>
                    </excludes>
                </configuration>
            </plugin>
        </plugins>
    </build>

注:spring-boot-configuration-processor引入后需要重启SpringBoot应用使该工具生效

配置文件:application.yml

person:
  last-name: libing
  age: 24
  birthday: 1997/08/21
  boos: true
  maps:
    k1: xxx
    k2: 111
  lists: [1,2,3]
  dog:
    name: xg
    age: 2

注:配置文件中的last-name ⇔ Person中的lastName属性,两种写法都可以

1.3.2 properties配置文件

JavaBean不变,注释掉application.yml中的内容。
application.properties,注意map和list的写法,与y(a)ml文件有很大差异

person.last-name=离能
person.age=24
person.birthday=1997/08/21
person.boos=true
person.maps.k1=xxx
person.maps.k2=111
person.lists=1,2,3
person.dog.name=xg
person.dog.age=2

遗留问题:IDEA properties文件中文乱码尚未解决,视频中的方法也不行
在这里插入图片描述
在这里插入图片描述

1.3.3 @Value和@ConfigurationProperties的区别

在这里插入图片描述
Tip:

  1. 松散绑定(Relaxed Binding)是一种属性名匹配规则,如下:
    在这里插入图片描述
  2. @Value注解value属性的值:字面量/${key}从环境变量、配置文件中获取值/#{SpEL}
    在这里插入图片描述

结论:
在某个业务逻辑中获取配置文件中的某项值,用@Value;
JavaBean和配置文件进行映射,用@ConfigurationProperties

1.3.4 @ConfigurationProperties和数据校验

导入坐标

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-validator</artifactId>
    <version>5.4.1.Final</version>
</dependency>

在这里插入图片描述
这样在将配置文件中的值注入JavaBean具体的属性之前,会进行校验,如果校验不通过,则无法进行注入

1.3.5 @PropertySource

加载指定的properties配置文件并将值注入到JavaBean的属性中
@ConfigurationProperties只能加载全局配置文件,如果是自定义的properties文件,是无法加载的,而@PropertySource可以。

首先自定义一个properties配置文件
在这里插入图片描述
JavaBean内容如下
在这里插入图片描述

1.3.6 @ImportResource

导入Spring的配置文件,让配置文件中的内容生效。用法是将@ImportResource标注在一个配置类(可以是主配置了也可以是其他配置类)上

自定义的Spring配置文件如下
在这里插入图片描述
主配置类如下
在这里插入图片描述
测试方法如下

package com.atguigu.springboot;

import com.atguigu.springboot.bean.Person;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;

@SpringBootTest
class SpringBoot01HelloworldQuickApplicationTests {

    @Autowired
    Person per;

//    自动注入Spring容器
    @Autowired
    ApplicationContext ioc;

    @Test
    void contextLoads() {
        System.out.println(per);
    }

    @Test
    void testImportResource(){
//        ioc.containsBean("helloService"):判断Spring容器中是否有helloService这个组件
        System.out.println(ioc.containsBean("helloService"));
    }
}

上述例子中beans.xml以配置文件的方式向Spring添加组件,SpringBoot并不推荐这样的方式。
Spring推荐给容器中添加组件的方式(全注解的方式):

  1. 新增一个配置类
    这里的配置类是跟配置文件等价的
  2. 使用@Bean给容器中添加组件

在这里插入图片描述

1.4 配置文件占位符

  1. 随机数
  2. 获取之前配置的值,如果之前没有设置可以用:指定默认值

在这里插入图片描述

1.5 Profile多环境支持

SpringBoot用于对不同环境提供不同的配置。实现的方式有两种,多Profile文件方式和多Profile文档块方式。

1.5.1 多Profile文件方式

在这里插入图片描述
在这里插入图片描述

  1. 适用于properties和y(a)ml文件
  2. 设置环境配置文件的格式:application-{环境标识}.properties/y(a)ml
  3. 环境标识支持自定义,一般,dev(开发环境)、prod(生产环境)、test(测试环境)
  4. 不额外指定激活,默认生效的环境是application.properties/application.y(a)ml

1.5.2 多Profile文档块方式

在这里插入图片描述
对于y(a)ml文件来说,可以通过指定主配置文件内部多Profile文档块设置多个环境,Profile文档块直接通过---进行分割,当指定的Profile文档块环境被激活后,该Profile文档块中的配置都被激活。

  1. 仅适用于y(a)ml文件
  2. 环境标识支持自定义,一般,dev(开发环境)、prod(生产环境)、test(测试环境)
  3. 不额外指定激活,默认生效的环境是application.yml中最顶部的Profile文档块

1.5.3 激活方式

即使主配置文件中没有进行多环境的配置(多Profile文档块、多Profile文件),也可以通过命令行和JVM参数激活不同的环境

  1. 配置文件激活:主配置文件内指定激活
    在这里插入图片描述
    在这里插入图片描述
  2. 命令行参数激活
    在这里插入图片描述
    或者打包后在运行jar包时通过java -jar XXX.jar --spring.profiles.active=环境标识指定
  3. JVM参数激活
    在这里插入图片描述

注:三种激活方式的优先级:配置文件<JVM参数<命令行参数

1.6 主配置文件的加载位置

主配置文件的加载位置是指主配置文件可以放在那些地方,这些地方SpringBoot都会进行加载。

  1. 当前项目下的config目录下
    在这里插入图片描述
  2. 当前项目根目录下
    在这里插入图片描述
  3. 类路径下的config目录下
    在这里插入图片描述
  4. 类路径根目录下
    在这里插入图片描述

上述四个位置的优先级是由高到低的,对于重叠的配置项,高优先级配置会覆盖低优先级配置,配置项不发生重叠的,互补配置
互补配置的好处:低优先级配置文件配置所有配置项,高优先级配置文件配置部分内容

另外,可以通过命令行参数的方式(- -spring.config.location)指定临时加载的配置文件位置,这种方式的配置文件优先级最高。

1. 7 外部配置加载顺序

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

  1. 命令行参数
  2. 来自java:comp/env的JNDI属性
  3. java系统属性(System.getProperties())
  4. 操作系统环境变量
  5. RandomValuePropertySource配置的random.*属性值
  6. jar包外部的application-{profile}.properties或application-{profile}.y(a)ml(带spring.profile的)配置文件
    application-{profile}.properties或application-{profile}.y(a)ml与jar包放在同一目录下就可生效
  7. jar包内部的application-{profile}.properties或application-{profile}.y(a)ml(带spring.profile的)配置文件
  8. jar包外部的application.properties或application.y(a)ml(不带spring.profile的)配置文件
  9. jar包内部的application.properties或application.y(a)ml(不带spring.profile的)配置文件
  10. @Configuration注解类上的@PropertySource
  11. 通过SpringApplication.setDefaultProperties指定的默认属性

6-9说明了优先加载带环境标识的配置文件,如果都是带环境标识的配置文件,加载顺序是先加载jar包外的,再加载jar包内的
这里的优先加载意思是哪个最终生效哪个就是优先加载,而不是优先加载的要优先读取

上述的加载来源并不是全部的,参考官方文档

1.8 自动配置原理

主配置文件能配置的属性参照

自动配置原理:

  1. SpringBoot启动的时候加载主配置类,开启了自动配置功能(@EnableAutoConfiguration)
  2. @EnableAutoConfiguration的作用
    2.1 利用EnableAutoConfigurationImportSelector给容器中导入一些组件
    2.2 具体导入了哪些组件从AutoConfigurationImportSelector类的selectImports()方法中可以查看
    2.3 selectImports()方法中有List<String> configurations = getCandidateConfigurations(annotationMetadata,attributes);这么一条语句,用于获取候选的配置
    2.4 getCandidateConfigurations()方法内部利用SpringFactoriesLoader.loadFactoryNames()扫描所有jar包类路径下的META-INF/spring.factories文件
    2.5 把扫描到的每一个文件的内容封装成Properties对象
    2.6 从封装后的这些Properties对象中获取到EnableAutoConfiguration.class类(类名)对应的值,这里的每个值都是一个XXXAutoConfiguration类,把他们添加到容器中,用他们来做自动配置
    在这里插入图片描述
  3. 每一个自动配置类进行自动配置功能,以HttpEncodingAutoConfiguration为例进一步解释自动配置原理
@Configuration  //表示这是一个配置类,跟以前的配置文件一样,也可以给容器中添加组件。
@EnableConfigurationProperties(HttpEncodingProperties.class)	//启动HttpEncodingProperties类的ConfigurationProperties功能,将配置文件中对应的值和HttpEncodingProperties绑定起来(配置文件的值注入到HttpEncodingProperties属性中),并把HttpEncodingProperties加入到IOC容器中
@ConditionalOnWebApplication	//涉及Spring底层的@Conditional注解,可以根据不同的条件,判定当前配置类是否生效。在这里的作用是,判断当前应用是否为Web应用,如果是,当前配置类才生效。
@ConditionalOnClass(CharacterEncodingFilter.class)	//判断当前项目有没有CharacterEncodingFilter(SpringMVC中解决乱码的过滤器)这个类
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)	//判断当前配置文件中是否存在spring.http.encoding=enabled这个配置,matchIfMissing = true表明,即使我们在配置文件中未配置该项,配置类也会生效。
public class HttpEncodingAutoConfiguration {

	//获取到的HttpEncodingProperties已经和配置文件进行了绑定。
	private final HttpEncodingProperties properties;

	//Spring中的构造函数注入,会从IOC容器中取出HttpEncodingProperties的对象,赋值给当前类的properties属性。
	public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
		this.properties = properties;
	}

	//自动配置类给容器中添加组件时,这些组件的某些值是要从properties中获取的
	@Bean
	@ConditionalOnMissingBean(CharacterEncodingFilter.class)
	public CharacterEncodingFilter characterEncodingFilter() {
		CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
		filter.setEncoding(this.properties.getCharset().name());
		filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
		filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
		return filter;
	}

一旦这个配置类生效,这个配置类就会给容器中添加各种组件,这些组件的属性是从对应的properties类中获取的,而这些properties类中的每一个属性又是和配置文件绑定的。

上面提到的XXXProperties类的属性和配置文件中的可配置项是一一对应的,配置文件中能配置的配置项就可以参考对应的XXXProperties类
在这里插入图片描述

整个自动配置过程的逻辑流程图如下
在这里插入图片描述
在这里插入图片描述

1.8.1 @Conditional&自动配置报告

@Conditional是Spring的注解,SpringBoot中有一些常用的派生注解,是基于@Conditional注解的,作用是当满足条件时后面的代码就会生效
在这里插入图片描述

SpringBoot中的自动配置类通常都是满足一定条件下才生效的,那我们怎么知道哪些自动配置类生效了呢,可以开启SpringBoot的Debug模式。
主配置文件中
在这里插入图片描述
这样,项目启动时控制台就会打印自动配置报告,告诉我们哪些自动配置类启用了,哪些没有启用
在这里插入图片描述
在这里插入图片描述

标签:系列,SpringBoot,配置文件,1x,配置,application,properties,加载
From: https://www.cnblogs.com/wzzzj/p/18039111

相关文章

  • SpringBoot 1x 系列之(一)SpringBoot 入门
    SpringBoot入门SpringBoot和微服务概念的简介、SpringBootHelloWorld入门程序、内部原理1.SpringBoot简介简化Spring应用开发(整个J2EE开发)的一个框架整个Spring技术栈的一个大整合.........J2EE开发的一站式解决方案注:SpringBoot使用嵌入式的Servlet容器,应用无......
  • Mybatis系列之(七)参数深入
    参数深入1.ParameterType(输入类型)1.1通过ParameterType传递Pojo对象Mybatis使用ognl表达式解析对象字段的值ognl表达式objectgraphicnavigationlanguage对象图导航语言通过对象的取值方法(属性的get方法)来获取数据,在写法上把get给省略了......
  • Mybatis系列之(六)MyBatis的CRUD操作
    MyBatis的CRUD操作CRUD操作指的是增加(Create)、检索(Retrieve)、更新(Update)和删除(Delete)操作1.编程步骤在dao接口中写方法映射配置文件中写对应的配置如果是Insert操作,占位符使用#{},括号中的内容要与实体类属性的get/set方法名保持一致(如果是通过右键生成的方法,......
  • Mybatis系列之(五)Mybatis在使用基于代理Dao的方式实现增删改查时都干了啥事儿
    Mybatis在使用基于代理Dao的方式实现增删改查时都干了啥事儿绝对路径:可能出现机器中没有D盘的情况,需要修改代码相对路径:部署项目后src就不存在了,需要修改代码基于以上两点,读取配置文件仅通过图中的两种方式进行读取构建者模式:专业的事儿由专业的人来做工厂模式:需要新的类的对......
  • Mybatis系列之(三)注解开发步骤
    注解开发步骤1.项目结构新建项目,创建与XML开发完全相同的项目结构删除resources/com文件夹2.全局配置文件修改SqlMapConfig.xml文件的mapper配置部分<!--指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件--><mappers><!--resource......
  • Mybatis系列之(二)Mybatis 入门
    Mybatis入门1.准备数据创建数据库eesy_mybatis,创建表user,插入数据2.pom文件打包方式<packaging>jar</packaging>导入坐标mybatis坐标mybatis官网文档-入门-安装<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> &......
  • Mybatis系列之(一)Mybatis 概述
    Mybatis概述1.三层架构解决持久层问题项目=框架(半成品)+业务需求表现层:展示数据业务层:业务需求持久层:数据库交互2.持久层技术解决方案2.1JDBC技术(规范)2.2Spring的JdbcTemplate(工具类)Spring中对JDBC的简单封装2.3Apache的DBUtils(工具类)对JDBC的简单封装3.......
  • SpringMVC系列之(十二)拦截器
    拦截器过滤器拦截器拦截器链1.过滤器与拦截器的比较过滤器是servlet规范中的一部分,任何Javaweb工程都可使用;拦截器是SpringMVC自己的,只能在SpringMVC工程中使用。过滤器可以对所有要访问的资源拦截;拦截器只能拦截访问的Controller方法,如果访问的是jsp、html、css、imag......
  • SpringMVC系列之(十一)异常处理
    异常处理1.未进行异常处理的异常传递流程2.SpringMVC异常处理流程3.SpringMVC异常处理开发步骤编写自定义异常类(做提示信息的)编写异常处理器配置异常处理器(跳转到错误提示页面)4.实现Controller中的方法packagecn.itcast.controller;importcn.itcast.domain.U......
  • SpringMVC系列之(十)文件上传
    文件上传1.文件上传的前提form表单的ectype属性(表单请求正文的类型)取值必须是multipart/form-data,默认值是application/x-www-form-urlencodedmethod属性值为post提供文件选择域<inputtype="file"/>2.文件上传的原理ectype=application/x-www-form-urlencoded(默认值)表......