SpringBoot 01 —— HelloSpringBoot、yaml配置、数据校验、多环境切换

系列文章

SpringBoot 01 —— HelloSpringBoot、yaml配置、数据校验、多环境切换
SpringBoot 02 —— Web简单探究、员工管理系统



一、SpringBoot简介

1、什么是Spring

​ Spring是一个从2003年兴起的轻量级Java开发框架,作者Rod Johnson。

​ Spring是为了解决企业级应用开发的复杂性而创建的,简化了开发。

2、Spring如何简化开发

  1. 基于POJO的轻量级和最小侵入性编程,所有东西都是bean;
  2. 通过IOC,依赖注入(DI)和面向接口实现松耦合;
  3. 基于切面(AOP)和惯例进行声明式编程;
  4. 通过切面和模版减少样式代码,RedisTemplate,xxxTemplate。

3、什么是SpringBoot

​ Spring Boot 基于 Spring 开发 , 它本身并不提供Spring框架的核心特性和扩展功能,即它不是用来替代Spring的解决方案,而是和Spring框架紧密结合的用于提升Spring开发者的体验一款工具。

​ Spring Boot以约定大于配置的核心思想,默认帮我们进行了很多设置,同时也集成了大量常用的第三方库配置(Redis、MongoDB等),这些第三方库几乎可以零配置的开箱即用。

​ 简单来说,Spring Boot其实不是什么新框架,只是它默认配置了很多框架,就像maven整合了所有jar包,Spring Boot整合了所有框架。

4、Spring Boot优点

  • 让所有Spring开发者更快入门
  • 开箱即用,提供各种默认配置来简化项目配置
  • 内嵌式容器简化Web项目(默认内嵌了Tomcat)
  • 没有冗余代码生成和XML配置的要求

二、Hello SpringBoot

Spring Boot创建项目有两种方式,通过Spring官方提供的工具可以快速构建,同时IDEA可以直接创建。
 

2.1、使用官方网站创建

  1. 打开https://start.spring.io/
  2. 填写项目信息
  3. 点击“ Generate Project ”生成项目,下载该压缩包。
  4. 解压项目,并用IDEA 以Maven方式导入。
  5. 第一次使用比较慢,会下载很多包。

在这里插入图片描述

2.2、使用IDEA直接创建

  1. 创建一个新项目
  2. 选择Spring initialize(这里的URL可以改用阿里的: https://start.aliyun.com/ )

在这里插入图片描述

3、和之前官网创建项目需要填的信息一样

在这里插入图片描述

4、选择Web依赖,如果不选,后面也可以自己在pom.xml中加。

在这里插入图片描述

在构建完项目后,选择Maven的package打包一下,如果环境都正常则能将项目打包成jar,最后显示SUCCESS BUILD就说明OK了,在target中找得到jar包。

在这里插入图片描述

2.3、创建过程出现的问题

1、Junit测试问题

在这里插入图片描述

可能需要在pom.xml的plugins中添加插件

<plugin>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.22.2</version>
    <configuration>
        <skipTests>true</skipTests>
    </configuration>
</plugin>

2、 Error:connect timed out

使用IntelliJ IDEA 创建SpringBoot项目时出现 Error:connect timed out 的解决方法

2.4、编写Hello SpringBoot

1、创建HelloController.java

在这里插入图片描述

package com.zcy.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/hello")
public class HelloController {
    
    

    @ResponseBody
    @RequestMapping("/springboot")
    public String hello(){
    
    
        return "Hello, Spring Boot";
    }
}

2、点击运行
在这里插入图片描述

3、在浏览器输入:http://localhost:8080/hello/springboot

在这里插入图片描述

4、可以修改tomcat的端口号,修改resources目录下的application.properties,新增

server.port=8081

2.5、小彩蛋

可以更改SpringBoot启动时的图案
在这里插入图片描述

1、在resources目录下新建一个banner.txt,可以去 https://www.bootschool.net/ascii 找心仪的图案拷贝到文件中。


//                          _ooOoo_                               //
//                         o8888888o                              //
//                         88" . "88                              //
//                         (| ^_^ |)                              //
//                         O\  =  /O                              //
//                      ____/`---'\____                           //
//                    .'  \\|     |//  `.                         //
//                   /  \\|||  :  |||//  \                        //
//                  /  _||||| -:- |||||-  \                       //
//                  |   | \\\  -  /// |   |                       //
//                  | \_|  ''\---/''  |   |                       //
//                  \  .-\__  `-`  ___/-. /                       //
//                ___`. .'  /--.--\  `. . ___                     //
//              ."" '<  `.___\_<|>_/___.'  >'"".                  //
//            | | :  `- \`.;`\ _ /`;.`/ - ` : | |                 //
//            \  \ `-.   \_ __\ /__ _/   .-` /  /                 //
//      ========`-.____`-.___\_____/___.-`____.-'========         //
//                           `=---='                              //
//      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^        //
//            佛祖保佑       永不宕机     永无BUG                    //

结果:

在这里插入图片描述

三、运行原理初探

3.1、pom.xml

进入pom.xml先看见一个父依赖,表明它依赖与一个父项目,其作用是管理项目的资源过滤和插件。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.4.3</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

按住Ctrl,鼠标左键点进去发现还有一个父依赖,这个就是真正管理SpringBoot里所有依赖版本的地方。

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-dependencies</artifactId>
    <version>2.4.3</version>
</parent>

以后我们导入的依赖是不需要写版本version的,但如果新导入的包没有在依赖中管理着就需要手动写版本。

3.2、启动器 spring-bost-start

在pom.xml中有这个依赖,它帮我们导入了web模块正常运行所需要的全部依赖组件

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

以后看见类似于 springboot-boot-starter-xxx ,就表明是spring-boot的场景启动器。

SpringBoot会将所有的功能场景都抽取出来,做成一个个的starter (启动器),只需要在项目中引入这些starter,所有相关的依赖都会导入进来 。

3.3、主启动类

默认的主启动类

//@SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
@SpringBootApplication
public class SpringbootApplication {
    
    
   public static void main(String[] args) {
    
    
     //这行代码会启动了一个服务
      SpringApplication.run(SpringbootApplication.class, args);
   }
}

现在我们点进注解@SpringBootApplication,看看都干了些什么。

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(
    excludeFilters = {
    
    @Filter(
    type = FilterType.CUSTOM,
    classes = {
    
    TypeExcludeFilter.class}
), @Filter(
    type = FilterType.CUSTOM,
    classes = {
    
    AutoConfigurationExcludeFilter.class}
)}
)
public @interface SpringBootApplication {
    
    
    // ......
}
  1. @ComponentScan

    这个注解在Spring中很重要 ,它对应XML配置中的元素。

    作用:自动扫描并加载符合条件的组件或者bean , 将这个bean定义加载到IOC容器中

  2. @SpringBootConfiguration

    作用:SpringBoot的配置类 ,标注在某个类上 , 表示这是一个SpringBoot的配置类;

    我们再进入这个注解查看

    // 点进去得到下面的 @Component
    @Configuration
    public @interface SpringBootConfiguration {
          
          }
    
    @Component
    public @interface Configuration {
          
          ...}
    

    这里的 @Configuration,说明这是一个配置类 ,配置类就是对应Spring的xml 配置文件;

    里面的 @Component 这就说明,启动类本身也是Spring中的一个组件而已,负责启动应用!

    我们回到 SpringBootApplication 注解中继续看。

  3. @EnableAutoConfiguration

    告诉SpringBoot开启自动配置功能,以前我们需要自己配置的东西,而现在SpringBoot可以自动帮我们配置 ;

    点进注解继续查看:

    @Import({
          
          Registrar.class})
    //自动配置包
    public @interface AutoConfigurationPackage {
          
          
        ....
    }
    

    @import :Spring底层注解@import , 给容器中导入一个组件。

    Registrar.class 作用:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring容器 ;

 这个分析完了,退到上一步,继续看

 **@Import({AutoConfigurationImportSelector.class}) :给容器导入组件 ;** 

 AutoConfigurationImportSelector :自动配置导入选择器,那么它会导入哪些组件的选择器呢?我们点击去这个类看源码: 

	a. 这个类中有一个这样的方法 

```java
// 获得候选的配置
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
    //这里的getSpringFactoriesLoaderFactoryClass()方法
    //返回的就是我们最开始看的启动自动导入配置文件的注解类;EnableAutoConfiguration
    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;
}
```

	b. 这个方法又调用了  SpringFactoriesLoader 类的静态方法!我们进入SpringFactoriesLoader类loadFactoryNames() 方法 

```java
public static List<String> loadFactoryNames(Class<?> factoryClass, @Nullable ClassLoader classLoader) {
    String factoryClassName = factoryClass.getName();
    //这里它又调用了 loadSpringFactories 方法
    return (List)loadSpringFactories(classLoader).getOrDefault(factoryClassName, Collections.emptyList());
}
```

	c. 我们继续点击查看 loadSpringFactories 方法 

```java
private static Map<String, List<String>> loadSpringFactories(@Nullable ClassLoader classLoader) {
    //获得classLoader , 我们返回可以看到这里得到的就是EnableAutoConfiguration标注的类本身
    MultiValueMap<String, String> result = (MultiValueMap)cache.get(classLoader);
    if (result != null) {
        return result;
    } else {
        try {
            //去获取一个资源 "META-INF/spring.factories"
            Enumeration<URL> urls = classLoader != null ? classLoader.getResources("META-INF/spring.factories") : ClassLoader.getSystemResources("META-INF/spring.factories");
            LinkedMultiValueMap result = new LinkedMultiValueMap();

            //将读取到的资源遍历,封装成为一个Properties
            while(urls.hasMoreElements()) {
                URL url = (URL)urls.nextElement();
                UrlResource resource = new UrlResource(url);
                Properties properties = PropertiesLoaderUtils.loadProperties(resource);
                Iterator var6 = properties.entrySet().iterator();

                while(var6.hasNext()) {
                    Entry<?, ?> entry = (Entry)var6.next();
                    String factoryClassName = ((String)entry.getKey()).trim();
                    String[] var9 = StringUtils.commaDelimitedListToStringArray((String)entry.getValue());
                    int var10 = var9.length;

                    for(int var11 = 0; var11 < var10; ++var11) {
                        String factoryName = var9[var11];
                        result.add(factoryClassName, factoryName.trim());
                    }
                }
            }

            cache.put(classLoader, result);
            return result;
        } catch (IOException var13) {
            throw new IllegalArgumentException("Unable to load factories from location [META-INF/spring.factories]", var13);
        }
    }
}
```

 	d. 发现一个多次出现的文件:spring.factories,全局搜索它 

  1. spring.factories

    我们根据源头打开spring.factories , 看到了很多自动配置的文件;这就是自动配置根源所在!

在这里插入图片描述

 我们在上面的自动配置类随便找一个打开看看,比如 :WebMvcAutoConfiguration 

![1614580173577](SpringBoot1.assets/1614580173577.png)

​	可以看到这些一个个的都是JavaConfig配置类,而且都注入了一些Bean,可以找一些自己认识的类,看着熟悉一下!

​	所以,自动配置真正实现是从classpath中搜寻所有的META-INF/spring.factories配置文件 ,并将其中对应的 org.springframework.boot.autoconfigure. 包下的配置项,通过反射实例化为对应标注了 @Configuration的JavaConfig形式的IOC容器配置类 , 然后将这些都汇总成为一个实例并加载到IOC容器中。	

结论:

  1. SpringBoot在启动的时候从类路径下的META-INF/spring.factories中获取EnableAutoConfiguration指定的值
  2. 将这些值作为自动配置类导入容器 , 自动配置类就生效 , 帮我们进行自动配置工作;
  3. 整个J2EE的整体解决方案和自动配置都在springboot-autoconfigure的jar包中;
  4. 它会给容器中导入非常多的自动配置类 (xxxAutoConfiguration), 就是给容器中导入这个场景需要的所有组件 , 并配置好这些组件 ;
  5. 有了自动配置类 , 免去了我们手动编写配置注入功能组件等的工作;

3.4、 SpringApplication

我最初以为就是运行了一个main方法,没想到却开启了一个服务;

@SpringBootApplication
public class SpringbootApplication {
    
    
    public static void main(String[] args) {
    
    
        SpringApplication.run(SpringbootApplication.class, args);
    }
}

SpringApplication.run分析

分析该方法主要分两部分,一部分是SpringApplication的实例化,二是run方法的执行;

  1. SpringApplication

    这个类主要做了以下四件事情:

    • 推断应用的类型是普通的项目还是Web项目
    • 查找并加载所有可用初始化器 , 设置到initializers属性中
    • 找出所有的应用程序监听器,设置到listeners属性中
    • 推断并设置main方法的定义类,找到运行的主类

    查看构造器:

    public SpringApplication(ResourceLoader resourceLoader, Class... primarySources) {
          
          
        // ......
        this.webApplicationType = WebApplicationType.deduceFromClasspath();
        this.setInitializers(this.getSpringFactoriesInstances();
        this.setListeners(this.getSpringFactoriesInstances(ApplicationListener.class));
        this.mainApplicationClass = this.deduceMainApplicationClass();
    }
    

  1. run方法流程分析

在这里插入图片描述

四、yaml

4.1、yaml是什么?

YAML是“ YAML Ain’t a Markup Language ”(YAML不是一种标记语言)的递归缩写,而在开发这种语言时,YAML的意思其实是 “Yet Another Markup Language”(仍是一种标记语言) 。

在之前的配置文件,我们大都是用XML配置,比如设置服务器端口号

XML配置:

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

yaml配置:

server: 
	port: 8080

显然,yaml要更加简洁。

4.2、yaml语法说明

SpingBoot的配置文件既可以用application.properties,也可以用application.yaml,但文件名称必须是application。

语法区别:

  • .properties:key=value
  • .yaml:key:空格value
  • yaml对空格非常严格,通过缩进来控制层次关系,左边对齐的一列数据都属于同一层级
#application.properties 是 key=value
#application.yaml 是 key:空格value

#普通的键值对
spring:
  application: spring-config

server:
  port: 8081

#对象
user:
  name: lihua
  age: 18
#在一行内完成
student: {
    
    name: lihua,age: 18}

#数组(List、set),用- 表示数组一个元素
pets:
  - cat
  - dog
  - pig
#在一行内完成
pets2: [cat, dog, pig]

注意:

  • 字符串默认是不需要加引号的

  • 如果加双引号:不会转义字符串的特殊字符,特殊字符如“\n”会正常输出回车

  • 如果加单引号:会转义特殊字符,例如 'A \n b’不会将\n变为回车

4.3、yaml注入

yaml文件的强大之处在于,它可以给我们的实体类注入值。

原来我们是这样给bean注入属性值的:

@Data
@AllArgsConstructor
@NoArgsConstructor
//上面三个注解是lombok,用于自动生成get\set\构造方法等
@Component//这个注解是注册bean到容器,能被Spring扫描到
public class Dog {
    
    
    @Value("小白")//属性注入值
    private String name;
    @Value("1")
    private int age;
}

如果要用lombok需要导入依赖,放在dependencies标签,而不是dependencyManagement

<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <version>1.18.12</version>
</dependency

在测试类中输出该类

@SpringBootTest
class SpringConfigApplicationTests {
    
    
    @Autowired
    private Dog dog;

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

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

现在换成一个更加复杂的类Person,我们使用yaml配置的方式进行注入

@Data
@NoArgsConstructor
@AllArgsConstructor
@Component 
//ConfigurationProperties是从全局配置从获取值,
//prefix指定配置文件中的前缀,与person下面的所有属性一一对应
//可以用 @PropertySource(value = "classpath:xxx.xxx")来加载指定文件
@ConfigurationProperties(prefix = "person")
public class Person {
    
    
    private String name;
    private Integer age;
    private Boolean happy;
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;
}

application.yaml

person:
  name: 李华${
    
    random.int} #可以用占位符,生成随机数
  age: ${
    
    random.int(15)} #随机数最大为15
  happy: true
  birth: 2000/01/01
  maps: {
    
    k1: v1,k2: v2}
  lists:
    - code
    - lol
    - music
  dog:
    name: 小白
    age: 1

出现这个问题时,可以点进去查看文档,里面需要我们导入一个依赖。

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

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-configuration-processor</artifactId>
	<optional>true</optional>
</dependency>

再进行测试:

Person(name=李华2137253950, age=1, happy=true, 
       birth=Sat Jan 01 00:00:00 CST 2000, 
       maps={
    
    k1=v1, k2=v2}, 
       lists=[code, lol, music], 
       dog=Dog(name=小白, age=1))

注意:如果yaml中的属性名和bean的属性名不同,则注入为null。

4.4、properteis注入

除了用yaml,我们当然也可以用properties注入,但yaml是官方推荐的方式。(properteis会乱码,去setting-FileEncoding该为UTF-8)

1614647857168

Dog.java

import org.springframework.stereotype.Component;

@Data
@AllArgsConstructor
@NoArgsConstructor
//上面三个注解是lombok,用于自动生成get\set\构造方法等
@Component//这个注解是注册bean到容器,能被Spring扫描到
@PropertySource(value = "classpath:dog.properties")
public class Dog {
    
    
    @Value("${dog.name}")//属性注入值
    private String name;
    @Value("#{2*3}")//#{SPEL} 这是Spring 表达式
    private int age;
}

编辑配置文件dog.properties

dog.name=小白
dog.age=12

4.5、对比

@ConfigurationProperties @Value
功能 可以批量注入配置文件中的属性 只能一个个指定
松散绑定 支持 不支持
SPEL 不支持 支持
JSR303数据校验 支持 不支持
复杂类型封装 不支持 支持
  1. @ConfigurationProperties只需要写一次,而用@Value赋值则需要每个字段都添加
  2. 松散绑定:比如在yaml中写user-name,等价于bean中userName,在-后面跟着的字母默认大写。
  3. JSR303数据校验:我们可以在字段上增加一层过滤器验证,来保证数据的合法性。
  4. 复杂类型封装,yaml中可以封装对象,而用value则不行。

因此,虽然使用yaml和properties都可以获取值,但更加推荐用yaml。如果某个业务中,只需要获取到配置文件中某一个值,那么可以用@value,但如果我们编写了JavaBean来与配置文件一一映射,则使用@ConfigurationProperties。

五、JSR303数据校验

需要先添加校验启动器

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

JSR303数据校验其实就是会校验我们的字段内容,例如

package com.zcy.pojo;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import org.springframework.validation.annotation.Validated;

import javax.validation.constraints.Email;

@Validated//该注解是开启验证
@ConfigurationProperties("test")
@Component
@Data
public class ValidationTest {
    
    
    @Email(message="邮箱格式错误")//message作用是自定义提示信息
    private String email;
}

application.yaml

#邮箱校验
test:
  email: 123456

结果:

在这里插入图片描述

常用注解

@Max(value=120)
@Email()

空检查
@Null       验证对象是否为null
@NotNull    验证对象是否不为null, 无法查检长度为0的字符串
@NotBlank   检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
@NotEmpty   检查约束元素是否为NULL或者是EMPTY.
    
Booelan检查
@AssertTrue     验证 Boolean 对象是否为 true  
@AssertFalse    验证 Boolean 对象是否为 false  
    
长度检查
@Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内  
@Length(min=, max=) string is between min and max included.

日期检查
@Past       验证 Date 和 Calendar 对象是否在当前时间之前  
@Future     验证 Date 和 Calendar 对象是否在当前时间之后  
@Pattern    验证 String 对象是否符合正则表达式的规则

六、多环境切换

真实开发中,我们肯定会有多套配置文件来适配不同环境,例如测试环境、开发环境,因此我们需要在多套环境中进切换。

6.1、properties方式

创建三个properties文件,如果我们用@ConfigurationProperties,那么都是默认从文件名为application的文件加载,如果需要切换,则在application.properties中加入下面代码:

spring.profiles.active=dev;#切换的文件只需要写—后面的内容

在这里插入图片描述

6.2、yaml方式

对于properties方式,不同环境需要创建不同文件,而用yaml则可以在一个文件内完成。

注意:如果.yaml和.properties同时配置端口,且都没有激活其他环境,则默认使用properties文件的。

server:
  port: 8081

#选择需要激活的环境
spring:
  profiles:
    active: dev

#不同环境用 --- 隔开
---
server:
  port: 8082
#给该环境命名
spring:
  profiles: dev

---
server:
  port: 8083
spring:
  profiles: test

6.3、配置文件的加载位置

我们的配置文件application.yaml一般都放在resources目录下,但其实也可以放在其他位置。

优先级1:项目路径下的config文件夹配置文件
优先级2:项目路径下配置文件
优先级3:资源路径下的config文件夹配置文件
优先级4:资源路径下配置文件
1614651371018

七、自动装配原理

思考一个问题:SpringBoot帮我们自动配置了什么?我们能修改吗?能修改哪些东西?能不能扩展?

我们以**HttpEncodingAutoConfiguration(Http编码自动配置)**为例解释自动配置原理;

例如

spring:
  mvc:
    hiddenmethod:
      filter:
        enabled: 
//表示这是一个配置类,和以前编写的配置文件一样,也可以给容器中添加组件;
@Configuration 

//启动指定类的ConfigurationProperties功能;
  //进入这个HttpProperties查看,将配置文件中对应的值和HttpProperties绑定起来;
  //并把HttpProperties加入到ioc容器中
@EnableConfigurationProperties({
    
    HttpProperties.class}) 

//Spring底层@Conditional注解
  //根据不同的条件判断,如果满足指定的条件,整个配置类里面的配置就会生效;
  //这里的意思就是判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnWebApplication(
    type = Type.SERVLET
)

//判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器;
@ConditionalOnClass({
    
    CharacterEncodingFilter.class})

//判断配置文件中是否存在某个配置:spring.http.encoding.enabled;
  //如果不存在,判断也是成立的
  //即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;
@ConditionalOnProperty(
    prefix = "spring.http.encoding",
    value = {
    
    "enabled"},
    matchIfMissing = true
)

public class HttpEncodingAutoConfiguration {
    
    
    //他已经和SpringBoot的配置文件映射了
    private final Encoding properties;
    //只有一个有参构造器的情况下,参数的值就会从容器中拿
    public HttpEncodingAutoConfiguration(HttpProperties properties) {
    
    
        this.properties = properties.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.autoconfigure.http.HttpProperties.Encoding.Type.REQUEST));
        filter.setForceResponseEncoding(this.properties.shouldForce(org.springframework.boot.autoconfigure.http.HttpProperties.Encoding.Type.RESPONSE));
        return filter;
    }
    //。。。。。。。
}

一句话总结 :根据当前不同的条件判断,决定这个配置类是否生效!

  • 一但这个配置类生效;这个配置类就会给容器中添加各种组件;
  • 这些组件的属性是从对应的properties类中获取的,这些类里面的每一个属性又是和配置文件绑定的;
  • 所有在配置文件中能配置的属性都是在xxxxProperties类中封装着;
  • 配置文件能配置什么就可以参照某个功能对应的这个属性类
//从配置文件中获取指定的值和bean的属性进行绑定
@ConfigurationProperties(prefix = "spring.http") 
public class HttpProperties {
    
    
    // .....
}

我们去配置文件里面试试前缀,看提示!

在这里插入图片描述

总结:

1、SpringBoot启动会加载大量的自动配置类

2、我们看需要的功能有没有在SpringBoot默认写好的自动配置类当中;

3、再看这个自动配置类中到底配置了哪些组件;(如果我们要用的组件存在其中,我们就不需要再手动配置)

4、给容器中自动配置类添加组件的时候,会从properties类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可;

xxxxAutoConfigurartion:自动配置类,给容器中添加组件

xxxxProperties:封装配置文件中相关属性;

因此,我们能修改的其实是Properties类中的属性

猜你喜欢

转载自blog.csdn.net/qq_39763246/article/details/114280578
今日推荐