前言

本文章说是 Spring Boot 这个框架都需要学习什么,不如说是 Spring Boot 框架都有什么需要学习。

对于初学者看看了解脉络还是很可以的,对于学完的高手看看可以总结查缺。

所以,这篇文章的目标是详细与简便兼具的一个要点,详细是有些东西多的地方就相对详细,简便意思是随时浏览随时清晰,而且本文会根据我的 Spring Boot 学习持续更新。

其实 Spring Boot 这个框架东西并没有那么多,但是前提是你学习了 Spring Framework,因为 Bean 的管理,IoC(控制反转)与 DI(依赖注入),AOP(面向切面编程),这些东西确实是有些难以理解和贴近框架底层的。

Spring Boot 框架其实不包含 ORM 框架,但是一般学的时候,好像都是带着 MyBatis 或 MyBatis-Plus, Spring Data JPA(Repository 接口、@Query等)和 JPA 规范与 Hibernate 一起学了。

Spring MVC 架构其实我是没有学的,因为感觉东西不少而且 Thymeleaf 或 FreeMarker(前后端不分离场景)用的不是很多,但是 MVC 架构打我第一个 Java 小项目就是用的这种设计模式,这种设计模式还是蛮舒服的。

RESTful API 开发 和 @Validated 参数校验什么的,还是有一些头疼的。


在学习 Spring Boot 之前,确保掌握以下知识:

JavaSE 基础:

基本的 Web 知识:

  • HTTP 协议基础(GET/POST 请求)。
  • Servlet
  • JSON 数据格式。

Maven 或 Gradle:学习如何管理依赖。

数据库MySQL

Spring Framework


认识 Spring 和 Spring Boot

我们刚开始学习 JavaWeb 的时候,使用 Servlet/JSP 做开发,一个接口搞一个 Servlet ,很头大,后来我们通过隐藏域或者反射等方式,可以减少 Servlet 的创建,但是依然不方便。

再后来,我们引入 Struts2/SpringMVC 这一类的框架,来简化我们的开发 ,和 Servlet/JSP 相比,引入框架之后,生产力确实提高了不少,但是用久了,又发现了新的问题,即配置繁琐易出错,要做一个新项目,先搭建环境,环境搭建来搭建去,就是那几行配置,不同的项目,可能就是包不同,其他大部分的配置都是一样的。

Java 总是被人诟病配置繁琐代码量巨大,这就是其中一个表现。那么怎么办?Spring Boot 应运而生,Spring Boot 是 Pivotal 团队在 2013 年开始研发的一个基于 Spring 的全新框架,试图将 Spring 中臃肿的配置进行简化,使 Java 开发更加轻量与快速,这个框架非常活跃,官方也非常重视。

从 Spring Boot 诞生的过程中,我们可以看到:

  1. Spring Boot 并非另起炉灶,而是在现有的 Spring 框架的基础上整出来的,它把 Spring 中繁琐的配置进行了简化。
  2. Spring Boot 降低了 Spring 家族的使用门槛,使新手更易上手 Spring 框架。

既然 Spring Boot 不是另起炉灶,那么 Spring Boot 学习要不要跳过 SSM 呢?

因为即使你跳过了 SSM 直接去学习 Spring Boot,实际上还是在学习 Spring 中的东西,那既然这样,我们还不如坐下来,老老实实把 Spring 过一遍。

Spring 我习惯叫做 Spring Framework

  • Spring Framework 是一个全面的框架,用于企业级开发。
  • 包括依赖注入 (DI)、面向切面编程 (AOP)、数据访问、事务管理等。

Spring Boot 是对 Spring 的简化和增强:

  • 无需繁琐配置(XML 配置,使用 properties)。
  • 提供内嵌服务器(Tomcat、Jetty)。
  • 快速启动 Web 应用程序。

官方文档: Spring Boot 官方文档


一、Spring Boot 基础入门

1. 核心思想与优势

  • 约定优于配置(Convention over Configuration):Spring Boot 遵循约定优于配置的原则,简单来说就是你所期待的配置与约定的配置一致,那么就可以不做任何配置,约定不符合期待时才需要对约定进行替换配置。它为开发者提供了一系列的默认配置,使得开发者可以快速搭建项目。例如,Spring Boot 默认使用嵌入式 Tomcat 作为服务器,默认的配置文件名为 application.propertiesapplication.yml
  • SpringBoot Starter:他将常用的依赖分组进行了整合,将其合并到一个依赖中,这样就可以一次性添加到项目的Maven或Gradle构建中。而且SpringBoot采用 JavaConfig 的方式对 Spring 进行配置,并且提供了大量的注解,极大的提高了工作效率。
  • 自动配置(Auto-Configuration)原理:Spring Boot 的自动配置功能是通过 spring-boot-autoconfigure 模块实现的。利用了Spring对条件化配置的支持,合理地推测应用所需的bean并自动化配置他们。该模块根据类路径下的依赖和配置信息,自动为应用程序配置所需的 Bean。例如,如果类路径下存在 H2 数据库的依赖,Spring Boot 会自动配置 H2 数据库的数据源。
  • 起步依赖(Starter Dependencies)的作用:起步依赖是 Spring Boot 提供的一种简化依赖管理的方式。它将一组相关的依赖打包成一个依赖,开发者只需要引入该依赖,就可以自动引入所需的所有依赖。例如,spring-boot-starter-web 依赖包含了 Spring MVC、嵌入式 Tomcat 等依赖。
  • 使部署变得简单:SpringBoot 内置了三种 Servlet 容器,Tomcat,Jetty,undertow。我们只需要一个Java的运行环境就可以跑 SpringBoot 的项目了,SpringBoot 的项目可以打成一个jar包。

2. 快速搭建项目

  • 使用 Spring Initializr 生成项目:Spring Initializr 是一个在线的项目生成工具,IDEA 集成了这个,很方便,它可以帮助我们快速生成 Spring Boot 项目。我们只需要选择项目的元数据、依赖和构建工具,就可以生成一个基本的 Spring Boot 项目。

  • 项目结构解析(src/main/javaresources 目录)src/main/java 目录是 Java 源代码的存放目录,我们可以在该目录下创建包和类。resources 目录是资源文件的存放目录,如配置文件、静态资源等。

    Spring Initializr 生成的标准项目结构如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    src
    ├── main
    │ ├── java
    │ │ └── com
    │ │ └── example
    │ │ └── demo
    │ │ ├── DemoApplication.java # 启动类
    │ │ ├── controller # 控制器层
    │ │ ├── service # 服务层
    │ │ ├── repository # 数据访问层(DAO)
    │ │ ├── entity # 实体类
    │ │ └── config # 配置类
    │ └── resources
    │ ├── application.properties # 配置文件
    │ ├── static # 静态资源(CSS/JS/图片)
    │ ├── templates # 模板文件(Thymeleaf/FreeMarker)
    │ └── META-INF
    │ └── resources # 元数据资源
    └── test
    └── java
    └── com
    └── example
    └── demo
    ├── DemoApplicationTests.java # 测试类
    ├── controller # 控制器测试
    └── service # 服务测试等等
    img
  • 启动类 @SpringBootApplication 的作用@SpringBootApplication 是一个组合注解,它包含了 @SpringBootConfiguration@EnableAutoConfiguration@ComponentScan 三个注解。@SpringBootConfiguration 表示该类是一个配置类,@EnableAutoConfiguration 启用自动配置功能,@ComponentScan 扫描组件。

3. 配置文件与优先级

  • application.properties vs application.ymlapplication.propertiesapplication.yml 都是 Spring Boot 支持的配置文件格式。application.properties 是传统的属性文件格式,使用键值对的方式进行配置。application.yml 是 YAML 格式的配置文件,使用缩进和冒号的方式进行配置,更加简洁易读。如果是2.4.0之前版本,优先级properties>yaml;但是如果是2.4.0的版本,优先级yaml>properties

  • 配置加载顺序(命令行参数 > 外部文件 > 内部配置):Spring Boot 会按照一定的顺序加载配置文件,命令行参数的优先级最高,其次是外部文件,最后是内部配置文件。但是通常情况下,我们认为,根目录下的config中的application.properties的优先级大于项目根目录下的application.properties,大于 resources文件夹config中的application.properties,大于resources文件夹根目录下的application.properties,并且相同配置文件按顺序加载可以实现互补,但是不会被覆盖。

  • 多环境配置(spring.profiles.active:我们可以使用 spring.profiles.active 属性来指定当前的环境,如开发环境、测试环境、生产环境等。Spring Boot 会根据该属性加载对应的配置文件,如 application-dev.propertiesapplication-test.propertiesapplication-prod.properties

  • 自定义配置项(@Value@ConfigurationProperties:我们可以使用 @Value 注解或 @ConfigurationProperties 注解来读取自定义配置项。@Value 注解用于读取单个配置项,@ConfigurationProperties 注解用于读取一组配置项。

  • 自定义application.properties配置文件注入IOC容器(属性注入的两种方式):Spring Boot 支持将自定义配置从 application.propertiesapplication.yml 直接注入到 Spring IOC 容器的 Bean 中,常用以下两种方式:

    • 使用 @Value 注解,适用于单个属性的注入,直接绑定到字段,适用于简单类型;

    • 使用 @ConfigurationProperties 注解:用于将配置文件(如 application.propertiesapplication.yml)中的属性适用于批量绑定一组配置到对象,还可以在公共 @Bean 方法上使用它,将属性绑定到控件之外的第三方组件。

      • 松散绑定:Spring Boot 使用一些宽松的规则将环境属性绑定到@ConfigurationProperties bean,因此环境属性名和 bean 属性名之间不需要完全匹配,比如在application.properties文件里定义一个 first-name=tom,而且可以支持多种命名风格的属性名,在对应 bean 类中使用 firstName 也能获取到对应的值,这就是松散绑定。

        1
        2
        3
        4
        5
        6
        7
        8
        # 标准驼峰式(Java 风格)
        app.user.firstName=John
        # 烤肉串式(Kebab Case,推荐)
        app.user.first-name=John
        # 蛇形式(Snake Case)
        app.user.first_name=John
        # 大写下划线式(UPPER_SNAKE_CASE)
        app.user.FIRST_NAME=John
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    @Component
    public class MyService {
    @Value("${custom.property.name}") // 读取配置项
    private String name;

    @Value("${custom.property.timeout:1000}") // 带默认值
    private int timeout;
    }

    /////////////////////////

    @Component
    @ConfigurationProperties(prefix = "custom") // 指定配置前缀
    public class CustomConfig {
    private String propertyName;
    private int timeout;
    private List<String> list;

    // 必须提供 Setter 方法
    public void setPropertyName(String propertyName) {
    this.propertyName = propertyName;
    }
    // 其他 Setter...
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    # 使用 @Value 注解
    custom.property.name=SpringBoot
    custom.property.timeout=2000

    # 使用 @ConfigurationProperties 注解
    custom:
    property-name: "SpringBoot"
    timeout: 2000
    list: ["a", "b", "c"]

二、Spring Boot 核心机制

1. 自动配置原理

  • spring-boot-autoconfigure 模块的作用spring-boot-autoconfigure 模块是 Spring Boot 自动配置的核心模块,它包含了大量的自动配置类。这些自动配置类根据类路径下的依赖和配置信息,自动为应用程序配置所需的 Bean。
  • @EnableAutoConfigurationMETA-INF/spring.factories@EnableAutoConfiguration 注解用于启用自动配置功能,它会扫描 META-INF/spring.factories 文件,该文件中定义了所有的自动配置类。
  • 条件注解(@ConditionalOnClass, @ConditionalOnMissingBean:条件注解是 Spring Boot 提供的一种灵活的配置方式,它可以根据条件来决定是否加载某个 Bean。例如,@ConditionalOnClass 注解表示只有当指定的类存在于类路径中时,才会加载该 Bean;@ConditionalOnMissingBean 注解表示只有当指定的 Bean 不存在时,才会加载该 Bean。
    • 关于条件注解的讲解:
      • @ConditionalOnBean:仅仅在当前上下文中存在某个对象时,才会实例化一个Bean。
      • @ConditionalOnClass:某个class位于类路径上,才会实例化一个Bean。
      • @ConditionalOnExpression:当表达式为true的时候,才会实例化一个Bean。基于SpEL表达式的条件判断。
      • @ConditionalOnMissingBean:仅仅在当前上下文中不存在某个对象时,才会实例化一个Bean。
      • @ConditionalOnMissingClass:某个class类路径上不存在的时候,才会实例化一个Bean。
      • @ConditionalOnNotWebApplication:不是web应用,才会实例化一个Bean。
      • @ConditionalOnWebApplication:当项目是一个Web项目时进行实例化。
      • @ConditionalOnNotWebApplication:当项目不是一个Web项目时进行实例化。
      • @ConditionalOnProperty:当指定的属性有指定的值时进行实例化。
      • @ConditionalOnJava:当JVM版本为指定的版本范围时触发实例化。
      • @ConditionalOnResource:当类路径下有指定的资源时触发实例化。
      • @ConditionalOnJndi:在JNDI存在的条件下触发实例化。
      • @ConditionalOnSingleCandidate:当指定的Bean在容器中只有一个,或者有多个但是指定了首选的Bean时触发实例化。
  • Spring Boot数据源自动配置:Spring Boot 的数据源自动配置主要通过spring-boot-autoconfigure模块实现,该模块是 Spring Boot 自动配置的核心模块,包含了大量的自动配置类,这些类会根据类路径下的依赖和配置信息,自动为应用程序配置所需的 Bean。对于数据源配置而言,它会根据项目中引入的数据库相关依赖(如 H2、MySQL 等),自动配置相应的数据源。
    • application.properties文件中数据源指定的命名规则是因为底层源码设定了需要这样才能获取,注入DataSourceProperties类对象中。数据源自动配置连接池默认指定Hikari,通过指定TYPE就可以实现更换连接池。
    • @EnableAutoConfiguration:这个注解用于启用自动配置功能,它会扫描META-INF/spring.factories文件,该文件中定义了所有的自动配置类。当 Spring Boot 应用启动时,@EnableAutoConfiguration会触发自动配置机制,让 Spring Boot 去查找并应用合适的数据源自动配置类。
    • META-INF/spring.factories:在这个文件中,会指定数据源自动配置类(如DataSourceAutoConfiguration),Spring Boot 启动时会读取该文件,加载相应的自动配置类。启动时,@EnableAutoConfiguration 会读取这些类并应用条件注解,决定是否生效。

2. Bean 管理与扩展

  • Spring Boot 对 Spring Bean 的增强:Spring Boot 在 Spring 的基础上对 Bean 管理进行了增强,如自动配置、条件注解等。这些增强功能使得我们可以更加方便地管理 Bean。
  • 自定义 Bean 覆盖默认配置(如替换内嵌 Tomcat):我们可以通过自定义 Bean 来覆盖 Spring Boot 的默认配置。例如,我们可以自定义一个嵌入式服务器 Bean,来替换默认的 Tomcat 服务器。
  • @Primary@Qualifier 解决 Bean 冲突:当存在多个相同类型的 Bean 时,我们可以使用 @Primary 注解来指定一个主要的 Bean,或者使用 @Qualifier 注解来指定具体的 Bean。

3. 内嵌容器与启动流程

  • 内嵌 Tomcat/Jetty/Undertow 的配置与切换:Spring Boot 默认使用嵌入式 Tomcat 作为服务器,我们可以通过修改依赖和配置来切换到 Jetty 或 Undertow 服务器。

  • 启动类 SpringApplication.run() 的源码简析SpringApplication.run() 方法是 Spring Boot 应用程序的启动入口,它会创建一个 Spring 应用上下文,并启动嵌入式服务器。

  • 自定义 Banner 与启动参数:我们可以通过在 resources 目录下创建 banner.txt 文件来自定义启动 Banner,也可以通过命令行参数或配置文件来设置启动参数。

  • 内嵌 tomcat 原理:Spring Boot 默认支持 Tomcat,Jetty,和 Undertow 作为底层容器。而 Spring Boot 默认使用Tomcat,一旦引入spring-boot-starter-web模块,就默认使用 Tomcat 容器。核心启动类在启动的时候,进入AutoConfigurationImportSelector类中的getAutoConfigurationEntry方法去各个模块 WEB-INF 下的spring.factories配置文件中加载相关配置类,获取到ServletWebServerFactoryAutoConfiguration自动配置类,也就是 tomcat 自动配置。ServletWebServerFactoryAutoConfiguration注解类中@Import引入的EmbeddedTomcat类里面TomcatServletWebServerFactory工厂类的getWebServer方法一旦被启动他就会创建并启动内嵌tomcat。

    • 总结内嵌 Tomcart 启动流程:

      • 触发自动配置:

        引入 spring-boot-starter-web 后,ServletWebServerFactoryAutoConfiguration 自动生效。

      • 创建 WebServer:

        TomcatServletWebServerFactorygetWebServer() 方法初始化 Tomcat 实例。

      • 端口绑定与启动:

        读取 server.port 配置(默认 8080),绑定端口并启动 Tomcat。

三、Spring Boot 集成与扩展

1. 数据访问

  • 整合 JDBC:spring-boot-starter-jdbc + DataSource 配置:我们可以使用 spring-boot-starter-jdbc 依赖来整合 JDBC,通过配置 DataSource 来连接数据库。
  • 整合 JPA:spring-boot-starter-data-jpa + 自动建表:使用 spring-boot-starter-data-jpa 依赖可以整合 JPA,Spring Data JPA 会根据实体类自动生成数据库表。
  • 整合 MyBatis:mybatis-spring-boot-starter + 注解 / XML 配置:通过 mybatis-spring-boot-starter 依赖可以整合 MyBatis,我们可以使用注解或 XML 文件来配置 SQL 语句。
  • 事务管理:@Transactional 的生效条件@Transactional 注解用于开启事务,它的生效条件包括方法必须是 public 的,类必须被 Spring 管理等。

2. Web 开发

  • 快速构建 RESTful API(@RestController@GetMapping 等):使用 @RestController 注解可以快速构建 RESTful API,@GetMapping 等注解用于处理 HTTP 请求。
  • 请求参数处理(@RequestParam@PathVariable@RequestBody@RequestParam 用于处理查询参数,@PathVariable 用于处理路径参数,@RequestBody 用于处理请求体。
  • 统一响应格式与全局异常处理(@ControllerAdvice:使用 @ControllerAdvice 注解可以实现统一响应格式和全局异常处理。
  • 文件上传与下载(MultipartFile:通过 MultipartFile 可以实现文件上传,使用 ResponseEntity 可以实现文件下载。

3. 安全与权限

  • 整合 Spring Security:spring-boot-starter-security:使用 spring-boot-starter-security 依赖可以整合 Spring Security,实现安全认证和授权。
  • 基础认证配置(内存用户、数据库用户):可以配置内存用户或从数据库中获取用户信息进行认证。
  • 自定义登录页与权限规则:可以自定义登录页和权限规则,实现个性化的安全配置。

4. 缓存与消息队列

  • 整合 Redis:spring-boot-starter-data-redis + RedisTemplate:使用 spring-boot-starter-data-redis 依赖可以整合 Redis,通过 RedisTemplate 可以操作 Redis 缓存。
  • 整合 RabbitMQ/Kafka:spring-boot-starter-amqp/kafka:使用 spring-boot-starter-amqpspring-boot-starter-kafka 依赖可以整合 RabbitMQ 或 Kafka 消息队列。
  • 声明式缓存(@Cacheable@CacheEvict:使用 @Cacheable 等注解可以实现声明式缓存,提高应用程序的性能。

5. 日志管理

  • SLF4J:SLF4J(Simple Logging Facade for Java)是日志门面,提供统一的日志 API,Spring Boot 默认使用 SLF4J 作为日志门面(抽象层),并集成了 Logback 作为默认的日志实现框架,允许开发者在不修改代码的情况下切换底层日志框架(如 Logback、Log4j2)。并集成 Logback 作为日志实现框架。由于每一个日志的实现框架都有自己的配置文件,所以在使用 SLF4j 之后,配置文件还是要使用实现日志框架的配置文件。

  • 统一日志依赖:Spring Boot 通过 spring-boot-starter-logging 默认引入 SLF4J + Logback,其他框架(如 MyBatis、Spring Security)的日志也会被桥接到 SLF4J。这意味着开发者在使用这些框架时,无需额外配置日志,所有日志都会统一输出。在 Maven 项目中,spring-boot-starter-web 依赖会自动引入 spring-boot-starter-logging

  • Spring Boot 的日志配置:开发者可以通过 SLF4J 提供的日志级别(如 TRACEDEBUGINFOWARNERROR)来控制日志的输出粒度。

    • 默认日志输出:
      • 控制台输出:Spring Boot 默认会将日志输出到控制台,INFO 级别及以上;
      • 文件输出:需手动配置 logging.file.namelogging.file.path
    • 日志级别配置:可以通过 logging.level 属性来配置不同包或类的日志级别。
    • 日志输出格式配置:可以通过 logging.pattern.consolelogging.pattern.file 来配置控制台和文件的日志输出格式。
    1
    2
    3
    4
    5
    6
    7
    8
    9
    logging:
    level:
    root: INFO
    com.example.demo: DEBUG # 包级别日志
    file:
    name: app.log # 日志文件路径
    pattern:
    console: "%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n"
    file: "%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n"
  • 自定义日志输出:可以在配置文件编写日志相关配置实现自定义日志输出。

    • 自定义 Logback:可以在 src/main/resources 目录下创建 logback-spring.xml 文件,进行自定义 Logback 配置。
  • 替换日志框架:虽然 Spring Boot 默认使用 Logback 作为日志实现框架,但开发者可以根据需要替换为其他日志框架,如 Log4j2。

    • 切换为 Log4j2

      排除默认 Logback

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <exclusions>
      <exclusion>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-logging</artifactId>
      </exclusion>
      </exclusions>
      </dependency>

      引入 Log4j2 Starter

      1
      2
      3
      4
      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-log4j2</artifactId>
      </dependency>

      配置 log4j2-spring.xml

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      <Configuration>
      <Appenders>
      <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5level %logger{36} - %msg%n"/>
      </Console>
      </Appenders>
      <Loggers>
      <Root level="info">
      <AppenderRef ref="Console"/>
      </Root>
      </Loggers>
      </Configuration>
  • 日志性能优化:在高并发场景下,日志输出可能会成为性能瓶颈。可以通过异步日志的方式来减少 I/O 阻塞,提升性能。

    Logback 配置示例:

    1
    2
    3
    <appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="FILE"/>
    </appender>

    Log4j2 配置示例

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <Configuration>
    <Appenders>
    <Async name="Async">
    <AppenderRef ref="File"/>
    </Async>
    </Appenders>
    <Loggers>
    <Root level="info">
    <AppenderRef ref="Async"/>
    </Root>
    </Loggers>
    </Configuration>

四、Spring Boot 高级特性

1. 自定义 Starter

  • 创建自己的 Starter 模块:可以创建一个独立的 Maven 或 Gradle 模块作为 Starter。

    • 实现:

      • 创建 Maven 模块:

        • 定义 xxx-spring-boot-starterxxx-spring-boot-autoconfigure 两个模块。
      • 编写自动配置类:

        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        @Configuration
        @ConditionalOnClass(MyService.class)
        @EnableConfigurationProperties(MyProperties.class)
        public class MyAutoConfiguration {
        @Bean
        @ConditionalOnMissingBean
        public MyService myService(MyProperties properties) {
        return new MyService(properties);
        }
        }
      • 注册配置类:在 src/main/resources/META-INF/spring.factories 中添加:

        1
        2
        org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
        com.example.MyAutoConfiguration
  • Spring Boot 中的 starter:Spring Boot 中的 starter 是一种非常重要的机制,能够抛弃以前繁杂的配置,将其统一集成进 starter,应用者只需要在 maven 中引入 starter 依赖,Spring Boot 就能自动扫描到要加载的信息并启动相应的默认配置。starter 让我们摆脱了各种依赖库的处理,需要配置各种信息的困扰。Spring Boot会自动通过 classpath 路径下的类发现需要的 Bean,并注册进 IOC 容器。Spring Boot提供了针对日常企业应用研发各种场景的 spring-boot-starter 依赖模块。所有这些依赖模块都遵循着约定成俗的默认配置,并允许我们调整这些配置,即遵循“约定大于配置”的理念。简而言之,starter 就是一个外部的项目,我们需要使用它的时候就可以在当前 Spring Boot 项目中引入它,Spring Boot会自动完成装配。

  • 编写 Auto-Configuration 类与条件注解:编写自动配置类和使用条件注解来实现自定义配置。

  • 打包并发布 Starter(供其他项目依赖):将 Starter 模块打包并发布到 Maven 仓库,供其他项目依赖。

  • 自定义Starter热插拔技术

2. 监控与管理

  • Actuator 端点(/health, /metrics, /env:Actuator 提供了一系列的端点,如 /health 用于检查应用程序的健康状态,/metrics 用于查看应用程序的指标信息。
  • 自定义健康检查(HealthIndicator:可以自定义健康检查类,实现 HealthIndicator 接口。
  • 整合 Prometheus 暴露指标:可以将 Actuator 的指标信息暴露给 Prometheus 进行监控。

3. 测试与调试

  • 单元测试:@SpringBootTest + MockMvc:使用 @SpringBootTest 注解进行集成测试,使用 MockMvc 进行模拟 HTTP 请求。

  • 测试切片(@WebMvcTest, @DataJpaTest:使用测试切片注解可以只加载部分组件进行测试。

  • 热部署(DevTools 的自动重启):通过 spring-boot-devtools 依赖实现热部署,可以实现不重启服务器情况下,对项目进行即时编译,修改代码后自动重启应用,提升开发效率。

    热部署就是我们在编辑器上启动项目,然后改动相关的代码,然后编辑器自动触发编译,替换掉历史的 .class 文件后,项目检测到有文件变更后会重启 spring boot 项目。内部主要是通过引入的插件对我们的 classpath 资源变化进行监听,当 classpath 有变化,才会触发重启。

4. 性能优化

  • 启动速度优化(懒加载 @Lazy:使用 @Lazy 注解可以实现 Bean 的懒加载,提高应用程序的启动速度。
  • 内存与线程池调优(Tomcat 线程池配置):可以通过配置 Tomcat 线程池来优化内存和性能。
  • 关闭不必要的自动配置(exclude 参数):使用 exclude 参数可以关闭不必要的自动配置,减少应用程序的启动时间。

5.Spring Boot缓存

  • 缓存概念及缓存注解:

  • 5个核心接口

  • 缓存注解@Cacheable实现

五、实战与部署

1. 项目实战

  • 从零搭建一个 Spring Boot 项目(含数据库、API、安全):按照前面所学的知识,从零开始搭建一个完整的 Spring Boot 项目,包括数据库连接、API 开发和安全认证。
  • 集成 Swagger 生成 API 文档(springdoc-openapi:使用 springdoc-openapi 依赖可以集成 Swagger,自动生成 API 文档。
  • 日志配置(Logback 日志分级与文件输出):使用 Logback 进行日志配置,实现日志分级和文件输出。

2. 打包与部署

  • 打包为可执行 JAR(mvn package:使用 mvn package 命令可以将项目打包为可执行 JAR 文件。
  • 打包为 WAR 包部署:修改 pom.xml 配置为 war,添加依赖<javax.serlvet>servlet 的 api,然后排除Spring Boot内置 Tomcat,最后需要改造启动类,打包交给外置 Tomcat 运行
  • JAR 与 WAR 的差异:
    • jar更加简单方便,使用 java -jar xx.jar 就可以启动。所以打成 jar 包的最多。而 war包可以部署到tomcat的 webapps 中,随Tomcat的启动而启动。具体使用哪种方式,应视应用场景而定。
    • 打jar包时不会把src/main/webapp 下的内容打到jar包里 (你认为的打到jar包里面,路径是不行的会报404)打war包时会把src/main/webapp 下的内容打到war包里。
    • 打成什么文件包进行部署与项目业务有关,就像提供 rest 服务的项目需要打包成 jar文件,用命令运行很方便。而有大量css、js、html,且需要经常改动的项目,打成 war 包去运行比较方便,因为改动静态资源可以直接覆盖,很快看到改动后的效果,这是 jar 包不能比的。
  • 多环境打包(-Pprod 激活生产配置):使用 -Pprod 参数可以激活生产环境的配置进行打包。线上环境prod(product)、开发环境dev(development)、测试环境test、提测环境qa、单元测试unitest等等多种环境进行不同配置。
  • Docker 化部署(编写 Dockerfile + 多阶段构建):编写 Dockerfile 并使用多阶段构建将项目打包为 Docker 镜像,实现容器化部署。
  • 监控插件-Acturator:Spring boot作为微服务框架,除了它强大的快速开发功能外,还有就是它提供了actuator模块,引入该模块能够自动为Spring boot应用提供一系列用于监控的端点。Spring Boot Actuator提供了对单个Spring Boot的监控,信息包含:应用状态、内存、线程、堆栈等等,比较全面的监控了Spring Boot应用的整个生命周期。
  • Actuator 的 REST 接口

3. 生产级配置

  • 健康检查与优雅停机:配置健康检查端点,实现应用程序的优雅停机。

  • 配置 HTTPS(SSL 证书):配置 SSL 证书,实现 HTTPS 访问。

  • 使用 Spring Boot Admin 监控多服务:使用 Spring Boot Admin 可以监控多个 Spring Boot 服务的运行状态。

六、扩展学习(Spring Boot 生态)

1. 响应式编程

  • Spring WebFlux(Reactive 编程):Spring WebFlux 是 Spring 提供的响应式编程框架,它基于 Reactor 库,支持异步、非阻塞的请求处理。
  • spring-boot-starter-webflux 构建响应式 API:使用 spring-boot-starter-webflux 依赖可以快速构建响应式 API。
  • 对比 MVC 与 WebFlux 的适用场景:MVC 适用于传统的同步请求处理场景,WebFlux 适用于高并发、异步的请求处理场景。

2. 云原生支持

  • 整合 Kubernetes(ConfigMap、Secret):可以将 Spring Boot 应用程序部署到 Kubernetes 集群中,使用 ConfigMap 和 Secret 进行配置管理。
  • 服务发现与配置中心(Spring Cloud 集成):通过 Spring Cloud 可以实现服务发现和配置中心,如使用 Eureka 进行服务发现,使用 Config Server 进行配置管理。
  • Service Mesh(Istio):可以使用 Istio 作为 Service Mesh 来管理 Spring Boot 应用程序的网络流量。

3. 源码深度

  • Spring Boot 启动流程源码分析:深入分析 Spring Boot 启动流程的源码,了解其内部实现原理。
  • 常用设计模式(工厂、单例、代理等):学习 Spring Boot 中常用的设计模式,如工厂模式、单例模式、代理模式等。
  • 核心注解 @SpringBootApplication 源码分析:分析 @SpringBootApplication 注解的源码,了解其背后的实现机制。
  • 自动配置加载流程追踪(Debug 启动过程):通过 Debug 启动过程,追踪自动配置的加载流程。

4. 版本意识

  • 注意 Spring Boot 2.x 与 3.x 的区别(如 Jakarta EE 9+)。Spring Boot 3.x 基于 Jakarta EE 9+,与 Spring Boot 2.x 有一些不兼容的地方,在升级时需要注意。

七、Spring Boot源码分析

1. spring-boot-starter-parent

2.spring-boot-starter-web

3.自动配置@SpringBootApplication

4.自动配置@SpringBootConfiguration

5.自动配置@ EnableAutoConfiguration

6.自动配置@Import(AutoConfigurationImportSelector .class)

7.AutoConfigurationEntry 方法

8.自动配置HttpEncodingAutoConfiguration

9.@ComponentScan注解

10.源码剖析Run方法整体流程

11.自动配置DispatcherServlet加载