Spring Boot:Spring Boot 入门、yaml 配置文件给属性赋值、自动装配原理详解

文章目录

  • [Spring Boot - 01](#Spring Boot - 01)
  • 一、概述
  • [二、第一个 Spring Boot 程序](#二、第一个 Spring Boot 程序)
  • 三、配置文件
    • [1. yaml 配置文件](#1. yaml 配置文件)
    • [2. 使用 yaml 配置文件给属性赋值](#2. 使用 yaml 配置文件给属性赋值)
    • [3. 松散绑定以及数据校验](#3. 松散绑定以及数据校验)
    • [4. 配置文件的位置以及多环境配置](#4. 配置文件的位置以及多环境配置)
  • [四、Spring Boot 分析](#四、Spring Boot 分析)
    • [1. pom.xml](#1. pom.xml)
    • [2. 启动器](#2. 启动器)
    • [3. 主程序](#3. 主程序)
    • [4. 自动装配原理](#4. 自动装配原理)
    • [5. 主启动类运行](#5. 主启动类运行)
  • 注意:

Spring Boot - 01

Spring Boot 官网点此进入


一、概述

  1. Spring Boot 核心思想:约定大于配置;

  2. Spring Boot 的主要优点

    • 为所有 Spring 开发者更快地入门;
    • 开箱即用 ,提供各种默认配置来简化项目配置;
    • 内嵌式容器简化 Web 项目;
    • 没有冗余代码生成和 XML 配置的要求。
  3. 单体应用架构(all in one)

    • 是指一个应用中的所有功能单元都封装在一个应用中,例如将数据库访问、Web 访问等各个功能都放到一个 war 包内;
    • 优点:易于开发和测试,方便部署,当需要扩展时,将 war 包复制多份,然后放在多个服务器上,再做个负载均衡即可;
    • 缺点:如果要修改某处,必须停掉整个服务,重新打包部署,并且对于大型应用,不可能把所有内容都放在一个应用中。
  4. 微服务架构

    • 把每个功能元素独立出来,然后将独立的功能元素动态组合,微服务架构是对功能元素进行复制,而没有对整个应用进行复制;
    • 优点 :节省了调用资源,并且每个功能元素都是一个可替换的、可独立升级的软件代码(高内聚,低耦合)。
  1. 微服务的具体阐述,中文翻译点此进入
  2. 微服务架构 中,各个功能元素完成自己的功能,然后通过 http 相互请求调用。例如 一个电商系统中,查缓存、连接数据库、结账、支付等服务都是一个个独立的功能元素,它们作为一个个微服务共同构建了一个庞大的系统,如果要修改其中的一个功能,只需要升级其中一个功能服务单元即可;
  3. Spring 为构建实现微服务,提供了从构建应用单元到完成大型分布式应用的方案
    • 使用 Spring Boot 可以构建一个个功能独立的微服务应用单元
    • 使用 Spring Cloud 可以实现分布式,完成大型分布式网络服务的调用;
    • 使用 Spring Cloud Data Flow 可以在分布式中间进行流式数据计算批处理等。

二、第一个 Spring Boot 程序

步骤

运行报错的情况

  1. 如果运行报错 :类文件具有错误的版本 61.0,应为 52.0,此时需要在 pom.xml 中降低 Spring Boot 的版本,这里降为 2.7.12;

  2. 如果运行报错:java 无效的目标发行版:17,此时需要修改两个地方,如图所示:

    • 打开 Settings 设置,修改 Java 编译器的版本为 1.8;
    • 打开项目结构,修改 Sources 和 Dependencies 为 1.8。


运行成功,并添加 controller 文件夹

说明

  1. 程序主入口所在的类由注解 @SpringBootApplication 声明,查看源码,发现该类是 Spring 的一个组件(@Component);
  2. controller 包一定要与程序主入口所在的类在同级目录;
  3. Spring Boot 使用 Tomcat 作为默认嵌入式容器
  4. 通过查看 pom.xml 文件,可以看到有一个父项目:spring-boot-starter-parent;
  5. 所有的 Spring Boot 依赖都是以 spring-boot-starter 开头的:
    • spring-boot-starter-web 依赖:包含了 SpringMVC,用于实现 http 接口;
    • spring-boot-starter-test 依赖:用于编写单元测试。

补充知识

  • 修改端口号 ,可以在 Spring Boot 的核心配置文件 application.properties 中配置:
properties 复制代码
# 修改端口号
server.port=8081
  • 自定义启动 Banner ,在线生成工具:点此进入,在 resources 包下新建 banner.txt,将 Banner 粘贴到文件中。

三、配置文件

Spring Boot 使用一个全局的配置文件 ,配置文件名称是固定的,为:application,而文件类型可以为 properties 或 yaml。

配置文件的作用:修改 Spring Boot 自动配置的默认值。

1. yaml 配置文件

yaml 是一个可读性高,用来表达数据序列化的格式

yaml 语法结构 :key : (空格) value,注意:一定要有空格!

yaml 复制代码
# 普通的键值对
name: Sun3285

# 对象
student: 
  name: Sun3285
  age: 24
  
student1: {name: Sun3285, age: 24}  # 行内写法

# 数组
teacher: 
  - 小张
  - 小明

teacher1: [小张, 小明]  # 行内写法

注意

  1. 字符串不一定要用双引号标识;
  2. 在缩排中空白字符的数目并不是非常重要,只要相同阶层的元素左侧对齐 就可以(注意不能使用 Tab 字符);
  3. 允许选择性加入空行,以增加可读性;
  4. 在 yaml 中可以使用缩写语法行内写法 ):
    • 数组 (一组按次序排列的值)用 [] 包括起来;
    • 对象 (键值对的集合)用 {} 包括起来。

2. 使用 yaml 配置文件给属性赋值

  • 之前:在 Spring 的 xml 配置文件中,注册 bean,然后通过依赖注入给属性赋值;

  • 现在 :在类上加注解注册为 bean,简单属性 可以使用注解 @Value 实现自动装配,复杂类型的属性可以使用 yaml 配置文件赋值。

实践:在程序主入口所在类的同级目录中,新建 pojo 包,建立 Dog 类和 Person 类。

使用 yaml 配置文件给属性赋值 ,并在 Java 类上使用注解 @ConfigurationProperties(prefix = "xxx") 声明

测试及结果

注意点

  • 键的名称不要有中文;

  • 在给对象属性赋值时,如果既使用了注解 @Autowired 自动装配,又使用了 yaml 配置文件赋值,最终会以 yaml 配置文件赋值

  • 使用注解 @ConfigurationProperties 的前提:这个类被注册,成为容器中的组件;

  • 在使用注解 @ConfigurationProperties 时,会有以下提示。解决办法:在 pom.xml 中添加以下依赖;

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>
  • 测试发现布尔类型的属性赋值为 null:
    • 原因 :在自动生成 set 方法时,方法名为 setHappy ,而 yaml 配置文件中键名为 isHappy ,两者不一致;
    • 改正方法 :修改 set 方法的方法名为 setIsHappy 修改 yaml 配置文件中键名为 happy ,使两者一致;
    • 可以发现 :使用 yaml 配置文件给属性赋值的本质 也是根据 set 方法来实现依赖注入

3. 松散绑定以及数据校验

松散绑定 :yaml 配置文件中的键名可以有下划线或中划线。

JSR303 数据校验 :在字段增加一层过滤器验证,可以保证数据的合法性。

实现方式

  • 在类上加注解 @Validated 声明;
  • 在 pom.xml 中导入 spring-boot-starter-validation 依赖;
  • 根据需要在属性上加对应注解声明,进行数据验证。
xml 复制代码
<!-- spring-boot-starter-validation -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-validation</artifactId>
    <version>3.0.1</version>
</dependency>

验证邮箱格式为例:

4. 配置文件的位置以及多环境配置

配置文件可以放置的位置 以及优先级 ,在官网上有详细说明:点此进入

可以根据开发、测试等不同场景配置多个环境 ,并选择激活使用哪一个配置文件。


四、Spring Boot 分析

1. pom.xml

  • 核心依赖在父工程 spring-boot-dependencies 中;
  • 在引入 Spring Boot 依赖时,不需要指定版本,因为在父工程中已经指定了版本

2. 启动器

  • 启动器就是 Spring Boot 的启动场景;
  • Spring Boot 会把所有的功能场景变成一个个的启动器,例如 spring-boot-starter-web 会自动导入 Web 环境所用到的所有依赖;
  • 我们要使用什么功能,只需要 导入对应的启动器即可,官网:点此进入

3. 主程序

接下来,将对主程序中的注解(自动装配原理 )和 main 方法(主启动类运行)进行分析。

4. 自动装配原理

  • @SpringBootConfiguration :声明是 Spring Boot 的配置文件,同时也是 Spring 的一个组件;
  • @ComponentScan :扫描当前主启动类同级的包;
  • @EnableAutoConfiguration自动导入包 ,将自动配置的类导入容器,使自动配置生效;
    • @AutoConfigurationPackage
      • 导入类 Registrar :自动注册包;
    • 导入类 AutoConfigurationImportSelector :自动导入选择器,是自动导入包的核心
      • getCandidateConfigurations 方法 :获取候选的配置 configurations;
        • 调用 SpringFactoriesLoader 类中的 loadFactoryNames 方法 :获取所有(主启动类)的加载配置;
          • loadFactoryNames 方法中调用本类中的 loadSpringFactories 方法 :获取自动配置类,遍历,封装。

过程

  1. Spring Boot 在启动时,从类路径 spring-boot-autoconfigure-2.7.12.jar/META-INF/spring.factories 下获取指定的值;
  2. spring.factories 中,所有的组件以类名的方式返回 ,将这些自动配置的类导入容器自动配置就会生效
  3. 有些自动配置类会被注解 @ConditionalOnxxx 声明,表示如果条件都满足,该自动配置类才会生效;
  4. 之前我们需要手动配置的东西,现在 Spring Boot 帮我们做了,用自动配置类代替了手动配置

总结 :Spring Boot 所有的自动配置类都是在启动的时候 扫描并加载到容器中,所有的自动配置类都在 spring.factories 中,但是不一定生效,要判断自动配置类被注解 @ConditionalOnxxx 声明的条件是否满足(是否导入了对应的启动器 starter,有了启动器,自动装配就会生效)。

补充 1

  • 注解 @Conditional 的扩展注解有 @ConditionalOnJava、@ConditionalOnClass、@ConditionalOnProperty 等等;
  • 这些扩展注解的作用 为:判断是否满足当前指定条件,如果满足,该自动配置类才会生效

补充 2 :配置文件的作用是修改 Spring Boot 自动配置的默认值,那么怎么知道配置文件中有哪些默认值呢?

  • 方式一 :官网:点此进入

  • 方式二推荐】:

    • 第一 :在 spring.factories 中可以找到所有的自动配置类,或者在 org 包中可以找到所有的类;
    • 第二 :找到自动配置类 xxxAutoConfiguration.java ,找到注解 @xxxProperties 中的配置属性类;
    • 第三 :这些配置属性类由注解 @ConfigurationProperties 声明,绑定了配置文件,就可以在 yaml 配置文件中配置修改这些属性值。


  • 补充 3 :在 yaml 配置文件中可以通过 debug: true 来看自动配置类哪些生效,哪些没有生效:

    • Positive matches :正匹配,自动配置类生效
    • Negative matches :负匹配,自动配置类没有生效
    • Unconditional classes没有条件的类
  • 补充 4:导入了自动配置类,为什么还要导入启动器?

    • :有些自动配置类会被注解 @ConditionalOnxxx 声明,表示如果条件都满足,该自动配置类才会生效,此时就需要导入启动器,满足所需条件

5. 主启动类运行

main 方法

java 复制代码
public static void main(String[] args) {
    SpringApplication.run(Springboot01Application.class, args);
}

说明 :run 方法中第一个参数 为应用入口的类,第二个参数为命令行参数。

SpringApplication 类主要做了以下四个事情

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

注意:

  1. 有目标,持续学习,不断进步!
  2. Spring Boot 官网https://spring.io/projects/spring-boot#overview
  3. 微服务的具体阐述,中文翻译链接:https://www.cnblogs.com/liuning8023/p/4493156.html
  4. Spring Boot 自定义启动 Banner 在线生成工具:https://www.bootschool.net/ascii
相关推荐
Asthenia041231 分钟前
Spring扩展点与工具类获取容器Bean-基于ApplicationContextAware实现非IOC容器中调用IOC的Bean
后端
bobz9651 小时前
ovs patch port 对比 veth pair
后端
Asthenia04121 小时前
Java受检异常与非受检异常分析
后端
uhakadotcom1 小时前
快速开始使用 n8n
后端·面试·github
JavaGuide1 小时前
公司来的新人用字符串存储日期,被组长怒怼了...
后端·mysql
bobz9651 小时前
qemu 网络使用基础
后端
Asthenia04122 小时前
面试攻略:如何应对 Spring 启动流程的层层追问
后端
Asthenia04122 小时前
Spring 启动流程:比喻表达
后端
Asthenia04122 小时前
Spring 启动流程分析-含时序图
后端
ONE_Gua3 小时前
chromium魔改——CDP(Chrome DevTools Protocol)检测01
前端·后端·爬虫