SpringBoot配置总结

导读:本篇文章讲解 SpringBoot配置总结,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com

概述

目标:掌握配置文件、加载顺序、配置原理。

配置文件

  • SpringBoot使用一个全局的配置文件,配置文件名称固定。
  1. application.properties
  2. application.yml
  • 配置文件的作用:修改SpringBoot自动配置的默认值;SpringBoot启动是在底层都给我自动配置好。
  • 配置文件存放在src/main/resources目录下或者 类路径/config下
  • yml是YAML(YAML Ain’t Markup Language)语言的文件,以数据为中心,比json、xml等更适合做配置文件。
  1. http://www.yaml.org/ 参考语法规范
  • 全局配置文件可以对默认配置进行修改
    在这里插入图片描述
    在这里插入图片描述

YAML语法

YAML基本语法

  • key:(空格)value:表示一对键值对,空格必须要有。
  • 使用缩进表示层级关系。
  • 缩进时不允许使用Tab键,只允许使用空格。
  • 缩进的空格数目不重要,只有相同层级的元素左侧对齐即可。
  • 大小写敏感。

YAML支持的三种数据结构

  • 对象:键值对的集合。
friends:
  lastName: zhangsan
  age: 20

行内写法:

friends: {lastName: zhangsan, age: 20}
  • 数组:一组按次序排列的值。
    用 – 值的方式表数组中的元素。
pets:
  - cat
  - dog
  - pig

行内写法:

pets: [cat,dog,pig]
  • 字面量:单个的、不可再分的值。
    字符串默认不用加上单引号或者双引号。
    “”双引号:不会转义字符串中的特殊字符,特殊字符会作为本身想表达的意思。
    比如:name: “zhangsan \n list”,输出结果:zhangsan
    list
    ”单引号:会转义特殊字符,特殊字符最终只是一个普通的字符串数据。
    比如:name: ‘zhangsan \n list’,输出结果:zhangsan \n list

YAML配置文件值获取

示例:新建Person类和Dog类,演示如何获取,字面量、数组、对象、map的配置信息

/**
 * 想获取配置信息,必须是容器中的bean,其实和bean初始化逻辑一种,配置文件的信息其实就是属性填充
 * @ConfigurationProperties 告诉Spring对象的值从配置文件中获取,prefix前缀表示从配置文件中哪个配置项下面获取属性值
 * 自动必须要有get/set方法,否则无法完成属性填充(其实属性就是字段+get/set方法)
 */
@Component
@ConfigurationProperties(prefix = "person")
public class Person {
    private String name;

    private int age;

    private String address;

    private List<Object> like;

    private Map<String, Object> maps;

    private Dog dog;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public List<Object> getLike() {
        return like;
    }
    public void setLike(List<Object> like) {
        this.like = like;
    }
    public Map<String, Object> getMaps() {
        return maps;
    }
    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }
    public Dog getDog() {
        return dog;
    }
    public void setDog(Dog dog) {
        this.dog = dog;
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                ", like=" + like +
                ", maps=" + maps +
                ", dog=" + dog +
                '}';
    }
}

public class Dog {
    private String name;
    private int age;
    @Override
    public String toString() {
        return "Dog{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
  • 添加配置处理器,可以在编写Yaml文件绑定对象是有相应的提示
<!--导入配置处理器后,配置文件进行绑定就会有智能提示功能,没其他作用-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
        </dependency>
  • 测试
    @SpringBootTest注解,用于单元测试,可以字段装配对象,无需手动context.getBean()获取bean对象。
@SpringBootTest
class PracticeApplicationTests {
    @Autowired
    private Person person;

    @Test
    public void testYAML() {
        System.out.println(person);
    }
}

测试结果:
在这里插入图片描述

properties配置

从properties中获取配置值

配置信息获取与yaml获取基本一致,只是在properties中写法不一样,其它完全一样。

  • 配置信息
person.name=wangwu
person.address=中国北京
person.age=18
person.like=旅游,电影
person.maps.k1=唱歌
person.maps.k2=跳舞
person.dog.name=小狗
person.dog.age=2
  • 获取结果
    在这里插入图片描述
    可以获取到数据,但是存在中文乱码问题。

解决乱码问题

产生乱码的原因
idea使用的utf8编码,但是properties使用的ASCII编码,因此需要在idea中把properties文件设置成utf8格式,同时转换成assii格式。
在这里插入图片描述

  • 获取结果无乱码
    在这里插入图片描述

@Value

普通变量获取配置信息

可以通过@Value注解在字段上给字段赋值,@Value与bean标签中的value配置作用一致,因此用法也一致。
示例:

@Component
public class Person {
    /**
     * 1. @Value类似于bean标签中的value配置;
     * 2. bean中的value可以配置:字面量;${key}获取环境变量、配置文件中的key值,#{SpEl}spring的EL表达式;
     * 因此@Value也可以配置上面的三种值。
     * 3. @Value获取配置信息,可以不写get/set方法。
     * <bean id = "person" class="xxxxx">
     *     <property name="address" value="xxx"></property>
     * </bean>
     */
    @Value("小明")
    private String name;
    @Value("#{11*2}")
    private int age;
    @Value("${person.address}")
    private String address;
    private List<Object> like;
    private Map<String, Object> maps;
    private Dog dog;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public List<Object> getLike() {
        return like;
    }
    public void setLike(List<Object> like) {
        this.like = like;
    }
    public Map<String, Object> getMaps() {
        return maps;
    }
    public void setMaps(Map<String, Object> maps) {
        this.maps = maps;
    }
    public Dog getDog() {
        return dog;
    }
    public void setDog(Dog dog) {
        this.dog = dog;
    }
    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                ", like=" + like +
                ", maps=" + maps +
                ", dog=" + dog +
                '}';
    }
}
  • 获取结果
    在这里插入图片描述

@Value注解配置默认值

@Value在注解模式下读取配置文件注入属性值
示例:

	@Value("${name}")	
	private String name;

但是,如果配置文件中没有设置name的值,spring在启动的时候会报错。这时需要给name配置默认值,代码如下:

	@Value("${name:bob}")
	private String name;

除了String类型外,其他类型也可配置默认值:

	@Value("${age:18}")
	private int age;

@Value注入列表或者数组

可以使用split()方法在一行中注入“列表”。
配置如下:
config.properties

server.name=hydra,zeus
server.id=100,102,103

AppConfigTest.java

package com.mkyong.analyzer.test;
 
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
 
@Configuration
@PropertySource(value="classpath:config.properties")
public class AppConfigTest {
	
	@Value("#{'${server.name}'.split(',')}")
	private List<String> servers;
	
	@Value("#{'${server.id}'.split(',')}")
	private List<Integer> serverId;
	
	//To resolve ${} in @Value
	@Bean
	public static PropertySourcesPlaceholderConfigurer propertyConfigInDev() {
		return new PropertySourcesPlaceholderConfigurer();
	}

}

注意如果配置项已逗号分隔,无需使用split方法,spring默认支持逗号的分隔。

可以指定默认值,下面的3种写法Spring都是支持的。

	@Value("#{'${server.id:127.0.0.1,192.168.1.18}'.split(',')}")
	private List<String> serverId;
 
	@Value("${server.id:127.0.0.1,192.168.1.18}")
	private List<String> serverId;
	
	@Value("${server.id:127.0.0.1,192.168.1.18}")
	private String[] serverId;

@Value给静态变量注入值

  • @Value不能直接给静态变量赋值,即使编译不报错,但是结果赋值不成功。
    @Value("${fastdfs.cache.redis.expireTime:86400}")
    public static int EXPIRE_TIME;

可以看到结果为0,没有赋值成功。
在这里插入图片描述

  • 静态变量赋值,@Value注解需要放在方法上
    类上加上@Component注解,方法名(例如setExpireTime,方法名可以随便写,通常以set开头)和参数名(例如expireTime,参数名也可以随便写),如下所示:
    /**
     * 缓存过期时间,单位秒
     */
    public static int EXPIRE_TIME;

    /**
     * 
     * @param expireTime 过期时间
     */
    @Value("${fastdfs.cache.redis.expireTime:86400}")
    public void setExpireTime(int expireTime) {
        EXPIRE_TIME = expireTime;
    }

测试结果,赋值成功。
在这里插入图片描述

@ConfigurationProperties与@Value的区别

@ConfigurationProperties @Value
功能 可以批量注入配置文件中的属性 只能一个个的指定
松散语法绑定(对象中的小驼峰命名与配置文件中-命令相互转换,比如:字段:lastName,可以在配置文件中写出last-name/last_name) 支持 不支持
SPEL表达式(Spring 表达式) 不支持 支持
JSR303数据校验(Java Specification Requests,JSR-303 是JAVA EE 6 中的一项子规范,叫做Bean Validation,Hibernate Validator 是 Bean Validation 的参考实现 . Hibernate Validator 提供了 JSR 303 规范中所有内置 constraint 的实现,除此之外还有一些附加的 constraint。) 支持 不支持
复杂类型获取(对象、Map、数组) 支持 不支持

配置文件yaml或者properties格式都行。

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

  • JSR303数据校验
    示例:校验name的数据类型是Email格式,实际上配置文件中并不是Email格式,属性值绑定报错。
    在这里插入图片描述
  • 结果报错
    在这里插入图片描述

@PropertySource与@ImportResource

@PropertySource

用来加载指定的配置文件

/**
 * 想获取配置信息,必须是容器中的bean,其实和bean初始化逻辑一种,配置文件的信息其实就是属性填充
 * @ConfigurationProperties
 *    1. 告诉Spring对象的值从配置文件中获取,prefix前缀表示从配置文件中哪个配置项下面获取属性值;
 *    2. 用来读取全局配置文件(resources/application.yml,resource/application.properties),
 *       如果全局配置文件信息太多,就需要按场景拆分,为了能够读取到配置需要使用@PropertySource注解指定配置文件
 * @PropertySource 指定具体需要映射的配置文件,可以通过数组一次性指定多个。
 *
 */
@Component
@PropertySource(value = "classpath:person.properties")
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
    private String name;

    private int age;

    private String address;

    private List<Object> like;

    private Map<String, Object> maps;

    private Dog dog;
    
	...
}

@ImportResource

用来导入Spring的配置文件,让配置文件里面的内容生效。
SpringBoot里面没有Spring的配置文件,我们自己编写的配置文件是不能识别的,
想让Spring的配置文件生效,加载进来,我们需要通过@ImportResource显示的标注在一个配置类上。

@ImportResource(locations = {"classpath:bean.xml"})
@SpringBootApplication
public class PracticeApplication {
    public static void main(String[] args) {
        SpringApplication.run(PracticeApplication.class, args);
    }
}
// 测试类
@SpringBootTest
class PracticeApplicationTests {
    @Autowired
    private ApplicationContext applicationContext;

    @Test
    public void testBean() {
        System.out.println(applicationContext.containsBean("helloService"));
    }
}
  • bean的配置文件
<?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 id="helloService" class="com.practice.springboot.practice.service.HelloService"></bean>
</beans>

SpringBoot推荐使用全注解配置

SpringBoot推荐给容器添加组件的方式是使用全注解的方式,而不是上面的@ImportResource导入xml配置的方式。

  1. 使用@Configuration配置来代替Spring配置文件;
  2. 使用@Bean给容器中添加组件;
/**
 * @Configuaration:类似Spring中的XML配置,可以让我们直接使用java编码的方式去配置Spring的组件。
 * @Bean:
 *   1. 类似于Spring中xml配置文件的bean标签;作用是把方法返回的对象添加到Spring容器中;
 *   2. 添加到容器中的对象的默认id值是方法名称。
 *
 */
@Configuration
public class MyAppConfig {
    @Bean
    public HelloService helloSer() {
        System.out.println("helloSer 对象创建");
        return new HelloService();
    }
}

// 测试类
@SpringBootTest
class PracticeApplicationTests {
    @Autowired
    private ApplicationContext applicationContext;
    @Test
    public void testBean() {
        System.out.println(applicationContext.containsBean("helloSer"));
    }
}
  • 测试结果
2021-04-09 17:13:58.119  INFO 13188 --- [           main] c.p.s.practice.PracticeApplicationTests  : Starting PracticeApplicationTests using Java 1.8.0_181 on DESKTOP-OTR8LPB with PID 13188 (started by asus in D:\work_space\practiceSpringboot)
2021-04-09 17:13:58.129  INFO 13188 --- [           main] c.p.s.practice.PracticeApplicationTests  : No active profile set, falling back to default profiles: default
helloSer 对象创建
2021-04-09 17:14:02.855  INFO 13188 --- [           main] o.s.s.concurrent.ThreadPoolTaskExecutor  : Initializing ExecutorService 'applicationTaskExecutor'
2021-04-09 17:14:03.530  INFO 13188 --- [           main] c.p.s.practice.PracticeApplicationTests  : Started PracticeApplicationTests in 6.417 seconds (JVM running for 9.251)
true
2021-04-09 17:14:04.203  INFO 13188 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor  : Shutting down ExecutorService 'applicationTaskExecutor'

配置文件占位符

随机数占位符

可以在配置文件application.properties或者其他properties的配置文件中使用随机数占位符

person.name=zhangsan${random.uuid}
// 比如下面这些类型
${random.value}${random.int}${random.long}${random.int(10)}${random.int[1024,65536]}

占位符代表的值

如果占位符之前配置的值,就是代表配置的值,如果之前没有配置就是占位符key,还可以使用:指定默认值(在占位符没有配置值的情况下,取默认值)

person.like=${person.hello:like}_movie

案例

  • application.properties 配置文件配置信息
person.name=zhangsan${random.uuid}
person.age=18
person.address=china_${person.name}
person.like=${person.hello:like}_movie

获取的值如下:

2021-04-10 12:47:45.736  INFO 1164 --- [           main] com.springboot.test.demo.TestConfig      : Started TestConfig in 1.738 seconds (JVM running for 3.678)
Person{name='zhangsanaeb3e706-2834-4c9f-a209-2f26ef371f71', address='china_zhangsan1c4cfdf7-771d-4122-b304-524da3574e9d', age=18, like='like_movie'}

Profile

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

多profile文件

我们在配置文件(默认配置文件:application.properties)编写的时候,文件名可以是:application-{profile}.properties/yml
例如:application-dev.properties、application-prod.properties
默认配置文件:application.properties
在这里插入图片描述

激活指定profile

  1. 配置文件方式激活
    在默认配置文件中指定spring.profiles.active=xxx,就可以激活相应的profile配置文件。
    比如:spring.profiles.active=prod
    在这里插入图片描述
    在这里插入图片描述
  2. 命令行激活(优先级最高)
    启动时添加 –spring.profiles.active=xxx
    命令行激活方式优先级高于配置文件/虚拟机方式,就是如果命令行、配置文件、虚拟机同时配置了,命令行的集合方式生效
    比如:
    java -jar practiceSpringboot.jar –spring.profiles.active=dev
  • 测试的时候可以在idea中的配置的program arguments 中传入命令行参数,不需要打包部署配置。
    在这里插入图片描述
    在这里插入图片描述
  1. jvm参数方式激活
    -Dspring.profiles.active=xxx
    在idea配置中如下:
    在这里插入图片描述

YAML文件多文档块模式

通过在yml文件中添加 — 来分割不同的文档,使用spring.profiles来定义不同文档的名称,如下所示:
在这里插入图片描述

配置文件加载位置

默认加载位置

spring boot启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件。

  1. file:./config/ 项目目录下的config文件夹下
    比如:与src同一个目录的config文件就是项目目录下的config文件夹。
    在这里插入图片描述
  2. file:./ 项目目录下
  3. classpath:/config/ 类路径下的config文件夹下,比如src/main/resource/config/
  4. classpath:/ 类路径下,比如src/main/resource/
  • 上面的优先级从高到低排序(1的优先级大于2的优先级…),所有位置的文件都会被加载,高优先级配置内容会覆盖低优先级配置内容;比如classpath:/config/ 下面的配置会覆盖 classpath:/ 下面的相同配置。
  • 我们也可以通过配置spring.config.location来改变默认配置。
  • springboot会从这四个位置全部加载主配置文件,互补配置(把4个地方的配置不同的key合在一起,相同的key高优先级覆盖低优先级)。

指定加载位置

我们还可以通过在命令行传入:spring.config.location来改变默认的配置文件位置,优先级最高,相同的key会被覆盖。
项目打包好以后,我们可以使用命令行参数的形式,启动项目的时候来指定配置文件的新位置;指定配置文件和默认加载的这些配置文件共同起作用形成互补配置。
示例如下:
在这里插入图片描述

外部配置加载顺序

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

  1. 命令行参数。
    可以在命令行指定所有默认配置(多个配置用空格隔开),优先级最高。
java -jar spring-boot.SNAPSHOT.jar --server.port=8087  --server.context-path=/abc
  1. 来自java:comp/env的JNDI属性。
  2. java系统属性(System.getProperties())。
  3. 操作系统环境变量。
  4. RandomValuePropertySource配置的random.*属性值。
  5. jar包外部的application-{profile}.properties或application.yml{带spring.profile}配置文件。
  6. jar包内部的application-{profile}.properties或application.yml{带spring.profile}配置文件。
  7. jar包外部的application.properties或者application.yml(不带spring.profile)配置文件。
    示例:
    在jar包外部编写配置文件application.properties与jar在同一个目录下,jar包启动时会优先加载外部application.properties的配置。
    在这里插入图片描述
# 无需指定配置文件,位置放置正确会自动加载外部的配置文件
java  -jar spring-boot.SNAPSHOT.jar
  1. jar包内部的application.properties或者application.yml(不带spring.profile)配置文件。
  2. @Configuration注解类上的 @PropertySource
  3. 通过SpringApplication.setDefaultProperties指定的默认属性。

自动配置原理

目标:配置文件到的写什么?怎么写?自动配置原理是什么?

所有配置项的属性信息

参考:
springboot配置项信息

自动配置原理

  1. Springboot启动的时候加载主配置类,开启了自动配置功能,自动配置功能开启由@EnableAutoConfiguration注解决定;
  2. @EnableAutoConfiguration作用
    在这里插入图片描述
    • 利用@EnableAutoConfigurationImportSelector给容器中导入一些组件。
    • 查看selectImports()方法的内容:
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(annotationMetadata);
            return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
        }
    }
 - 获取候选的配置
List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
    protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
        Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you are using a custom packaging, make sure that file is correct.");
        return configurations;
    }
    protected Class<?> getSpringFactoriesLoaderFactoryClass() {
        return EnableAutoConfiguration.class;
    }

List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
// 扫描所有Jar包类路径下   META-INF/spring.factories,把扫描到的这些文件的内容包装成properties对象
Properties properties = PropertiesLoaderUtils.loadProperties(resource);
// 从properties中获取到EnableAutoConfiguration.class类名对应的值,然后把它们添加到容器中。
(List)loadSpringFactories(classLoaderToUse).getOrDefault(factoryTypeName, Collections.emptyList());
  1. springboot启动时根据配置的@EnableAutoConfiguration注解,将类路径下所有的 META-INF/spring.factories里面配置的EnableAutoConfiguration的值加入到容器中;
  2. 每一个下面的xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中,用它们来做自动配置。
# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
org.springframework.boot.autoconfigure.batch.BatchAutoConfiguration,\
org.springframework.boot.autoconfigure.cache.CacheAutoConfiguration,\
org.springframework.boot.autoconfigure.cassandra.CassandraAutoConfiguration,\
org.springframework.boot.autoconfigure.context.ConfigurationPropertiesAutoConfiguration,\
org.springframework.boot.autoconfigure.context.LifecycleAutoConfiguration,\
org.springframework.boot.autoconfigure.context.MessageSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.context.PropertyPlaceholderAutoConfiguration,\
org.springframework.boot.autoconfigure.couchbase.CouchbaseAutoConfiguration,\
org.springframework.boot.autoconfigure.dao.PersistenceExceptionTranslationAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.cassandra.CassandraRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.couchbase.CouchbaseRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.elasticsearch.ReactiveElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jdbc.JdbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.jpa.JpaRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.ldap.LdapRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.mongo.MongoRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jReactiveRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.neo4j.Neo4jRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.solr.SolrRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcDataAutoConfiguration,\
org.springframework.boot.autoconfigure.data.r2dbc.R2dbcRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.data.redis.RedisRepositoriesAutoConfiguration,\
org.springframework.boot.autoconfigure.data.rest.RepositoryRestMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.data.web.SpringDataWebAutoConfiguration,\
org.springframework.boot.autoconfigure.elasticsearch.ElasticsearchRestClientAutoConfiguration,\
org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration,\
org.springframework.boot.autoconfigure.freemarker.FreeMarkerAutoConfiguration,\
org.springframework.boot.autoconfigure.groovy.template.GroovyTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.gson.GsonAutoConfiguration,\
org.springframework.boot.autoconfigure.h2.H2ConsoleAutoConfiguration,\
org.springframework.boot.autoconfigure.hateoas.HypermediaAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastAutoConfiguration,\
org.springframework.boot.autoconfigure.hazelcast.HazelcastJpaDependencyAutoConfiguration,\
org.springframework.boot.autoconfigure.http.HttpMessageConvertersAutoConfiguration,\
org.springframework.boot.autoconfigure.http.codec.CodecsAutoConfiguration,\
org.springframework.boot.autoconfigure.influx.InfluxDbAutoConfiguration,\
org.springframework.boot.autoconfigure.info.ProjectInfoAutoConfiguration,\
org.springframework.boot.autoconfigure.integration.IntegrationAutoConfiguration,\
org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JdbcTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.JndiDataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.XADataSourceAutoConfiguration,\
org.springframework.boot.autoconfigure.jdbc.DataSourceTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration,\
org.springframework.boot.autoconfigure.jmx.JmxAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.JndiConnectionFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.activemq.ActiveMQAutoConfiguration,\
org.springframework.boot.autoconfigure.jms.artemis.ArtemisAutoConfiguration,\
org.springframework.boot.autoconfigure.jersey.JerseyAutoConfiguration,\
org.springframework.boot.autoconfigure.jooq.JooqAutoConfiguration,\
org.springframework.boot.autoconfigure.jsonb.JsonbAutoConfiguration,\
org.springframework.boot.autoconfigure.kafka.KafkaAutoConfiguration,\
org.springframework.boot.autoconfigure.availability.ApplicationAvailabilityAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.embedded.EmbeddedLdapAutoConfiguration,\
org.springframework.boot.autoconfigure.ldap.LdapAutoConfiguration,\
org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderAutoConfiguration,\
org.springframework.boot.autoconfigure.mail.MailSenderValidatorAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.embedded.EmbeddedMongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration,\
org.springframework.boot.autoconfigure.mongo.MongoReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.mustache.MustacheAutoConfiguration,\
org.springframework.boot.autoconfigure.neo4j.Neo4jAutoConfiguration,\
org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration,\
org.springframework.boot.autoconfigure.quartz.QuartzAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcAutoConfiguration,\
org.springframework.boot.autoconfigure.r2dbc.R2dbcTransactionManagerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketRequesterAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketServerAutoConfiguration,\
org.springframework.boot.autoconfigure.rsocket.RSocketStrategiesAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.UserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.servlet.SecurityFilterAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.reactive.ReactiveUserDetailsServiceAutoConfiguration,\
org.springframework.boot.autoconfigure.security.rsocket.RSocketSecurityAutoConfiguration,\
org.springframework.boot.autoconfigure.security.saml2.Saml2RelyingPartyAutoConfiguration,\
org.springframework.boot.autoconfigure.sendgrid.SendGridAutoConfiguration,\
org.springframework.boot.autoconfigure.session.SessionAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.servlet.OAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.client.reactive.ReactiveOAuth2ClientAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.servlet.OAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.security.oauth2.resource.reactive.ReactiveOAuth2ResourceServerAutoConfiguration,\
org.springframework.boot.autoconfigure.solr.SolrAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskExecutionAutoConfiguration,\
org.springframework.boot.autoconfigure.task.TaskSchedulingAutoConfiguration,\
org.springframework.boot.autoconfigure.thymeleaf.ThymeleafAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration,\
org.springframework.boot.autoconfigure.transaction.jta.JtaAutoConfiguration,\
org.springframework.boot.autoconfigure.validation.ValidationAutoConfiguration,\
org.springframework.boot.autoconfigure.web.client.RestTemplateAutoConfiguration,\
org.springframework.boot.autoconfigure.web.embedded.EmbeddedWebServerFactoryCustomizerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.HttpHandlerAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.ReactiveWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.WebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.error.ErrorWebFluxAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.ClientHttpConnectorAutoConfiguration,\
org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.reactive.WebSocketReactiveAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketServletAutoConfiguration,\
org.springframework.boot.autoconfigure.websocket.servlet.WebSocketMessagingAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.WebServicesAutoConfiguration,\
org.springframework.boot.autoconfigure.webservices.client.WebServiceTemplateAutoConfiguration
  1. 每一个自动配置类进行自动配置功能;
  2. 以HttpEncodingAutoConfiguration为例接受自动配置原理;
// 表示这是一个配置类,与以前编写的配置文件一样,也可以给容器中添加组件
@Configuration(
    proxyBeanMethods = false
)
// 启动指定类的ConfigurationProperties功能,将配置文件中对于的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到spring的ioc容器中。
@EnableConfigurationProperties({ServerProperties.class})
// Spring底层@Conditional注解,根据不同的条件,如果满足指定的条件,整个配置类里面的配置才会生效;
// 判断当前应用是否是web应用,如果是当前配置类生效。
@ConditionalOnWebApplication(
    type = Type.SERVLET
)
// 判断当前项目中有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
@ConditionalOnClass({CharacterEncodingFilter.class})
// 判断配置文件中是否存在某个配置 server.servlet.encodind.enabled;
// matchIfMissing = true如果不存在判断也是成立的;
// 总结:即使我们配置文件中不配置server.servlet.encoding.enabled=true,也是默认生效的
@ConditionalOnProperty(
    prefix = "server.servlet.encoding",
    value = {"enabled"},
    matchIfMissing = true
)
public class HttpEncodingAutoConfiguration {
	// 它已经和springboot的配置文件映射了
    private final Encoding properties;
    // 只有一个有参构造器的情况下,参数的值就会从容器中获取。
    public HttpEncodingAutoConfiguration(ServerProperties properties) {
        this.properties = properties.getServlet().getEncoding();
    }
    // 给容器添加一个组件,这个组件的某些值需要从properties中获取。
    @Bean
    @ConditionalOnMissingBean
    public CharacterEncodingFilter characterEncodingFilter() {
        CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
        filter.setEncoding(this.properties.getCharset().name());
        filter.setForceRequestEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.REQUEST));
        filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.web.servlet.server.Encoding.Type.RESPONSE));
        return filter;
    }

根据当前不同的条件判断,决定这个配置类是否生效。
一旦这个配置类生效,这个配置类就会给容器中添加各种组件,这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的。

  1. 所有配置文件中能配置的属性都是在xxxProperties类中封装着
    配置文件能配置什么就可以参照某个功能对应的这个属性类。
// 从配置文件中获取指定的值和bean的属性进行绑定
@ConfigurationProperties(
    prefix = "server",
    ignoreUnknownFields = true
)
public class ServerProperties {
    private Integer port;

总结

  1. SpringBoot启动会加载大量的自动配置类
  2. 我们看需要的功能有没有springboot默认写好的自动配置类;
  3. 我们再来看这个自动配置类到底配置了哪些组件(只要我们要用的组件有,我们就不需要再来配置了)
  4. 给容器中自动配置类添加组件的时候,会从xxxProperties类中获取某些属性,我们就可以在配置文件中指定这些属性的值。
  5. 相关自动配置类的作用
    xxxAutoConfigration:自动配置类,给容器中添加组件;
    xxxProperties:封装配置文件中相关属性;

@Conditional与自动配置报告

@Conditional注解

必须是@Conditional指定的条件成立,才给容器添加组件,配置类里面的内容才会生效。
在这里插入图片描述
自动配置必须在一定条件下才能生效。

自动配置报告

  1. 有哪些自动配置类
    spring-boot-autoconfigure\2.4.4\spring-boot-autoconfigure-2.4.4.jar!\META-INF\spring.factories
    文件下的org.springframework.boot.autoconfigure.EnableAutoConfiguration键对应的值。
  2. 哪些配置类会生效
    如何判断哪些配置类是否生效呢?
  • 可以通过看代码,看@Conditionalxxx条件是否成立,如下:
    @ConditionalOnMissingClass({"org.aspectj.weaver.Advice"})
    @ConditionalOnProperty(
        prefix = "spring.aop",
        name = {"proxy-target-class"},
        havingValue = "true",
        matchIfMissing = true
    )
    static class ClassProxyingConfiguration {
        ClassProxyingConfiguration(BeanFactory beanFactory) {
            if (beanFactory instanceof BeanDefinitionRegistry) {
                BeanDefinitionRegistry registry = (BeanDefinitionRegistry)beanFactory;
                AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry);
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }

        }
    }
  • 看debug模式下的报告
    在配置文件中指定:debug=true
    在这里插入图片描述
    控制台的自动配置报告:
============================
CONDITIONS EVALUATION REPORT
============================

# 启用的自动配置
Positive matches:
-----------------

   AopAutoConfiguration matched:
      - @ConditionalOnProperty (spring.aop.auto=true) matched (OnPropertyCondition)

   AopAutoConfiguration.ClassProxyingConfiguration matched:
      - @ConditionalOnMissingClass did not find unwanted class 'org.aspectj.weaver.Advice' (OnClassCondition)
      - @ConditionalOnProperty (spring.aop.proxy-target-class=true) matched (OnPropertyCondition)

   DispatcherServletAutoConfiguration matched:
      - @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet' (OnClassCondition)
      - found 'session' scope (OnWebApplicationCondition)

   DispatcherServletAutoConfiguration.DispatcherServletConfiguration matched:
      - @ConditionalOnClass found required class 'javax.servlet.ServletRegistration' (OnClassCondition)
      - Default DispatcherServlet did not find dispatcher servlet beans (DispatcherServletAutoConfiguration.DefaultDispatcherServletCondition)

# 没启用的自动配置类
  Negative matches:
-----------------

   ActiveMQAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)

   AopAutoConfiguration.AspectJAutoProxyingConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required class 'org.aspectj.weaver.Advice' (OnClassCondition)

   ArtemisAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required class 'javax.jms.ConnectionFactory' (OnClassCondition)

   BatchAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required class 'org.springframework.batch.core.launch.JobLauncher' (OnClassCondition)
  
......

我们可以通过查看打印报告的方式快速确定哪些配置类被启用,可以很方便的对项目进行配置。

参考

  1. https://www.bilibili.com/video/BV1gW411W76m?p=19&spm_id_from=pageDriver
  2. SpringBoot使用@Value给静态变量注入值

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由半码博客整理,本文链接:https://www.bmabk.com/index.php/post/100355.html

(1)

相关推荐

半码博客——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!