Spring Boot开发的两大流派

Spring Boot 从 2 开始,分为了两大流派:
- 响应式栈(Reactive Stack )和 Servlet 栈(Servlet Stack )。
响应式栈(Reactive Stack )
- 框架:Spring WebFlux ,是一个非阻塞的 Web 框架,充分利用多核下一代处理器的优势,能处理大量并发连接。
- 底层支持:依赖 Netty、Servlet 3.1 + 容器 ,并通过响应式流适配器(Reactive Streams Adapters)实现。
- 相关组件
- Spring Security Reactive:响应式安全组件。
- Spring WebFlux:核心的响应式 Web 框架。
- Spring Data Reactive Repositories:支持 Mongo、Cassandra、Redis、Couchbase、R2DBC 等数据库的响应式数据仓库。
响应式栈主要好处和特点是很好的压榨了多核心 CPU 的能力,基于缓冲区机制和调度器去调度 CPU ,去处理大量的请求和实现高并发这种功能。这其实也就是我们常说的 非阻塞 I/O,以 Spring WebFlux 为核心框架 ,基于异步非阻塞方式,不阻塞线程等待 I/O 操作完成,充分利用多核处理器优势,能高效处理大量并发连接,提升系统吞吐量。支持多种异步框架,依赖 Netty 等框架及 Servlet 3.1 + 容器,提供异步 I/O 能力。
而且响应式栈基于响应式的编程模型,遵循响应式流规范,基于事件驱动的异步数据流处理模式,少量线程就能处理众多请求,资源利用高效。
Servlet 栈(Servlet Stack )
- 框架:Spring MVC ,基于 Servlet API 构建,采用同步阻塞 I/O 架构,一个请求对应一个线程模型。
- 底层支持:依赖 Servlet 容器和 Servlet API 。
- 相关组件
- Spring Security:传统安全组件。
- Spring MVC:传统的 MVC 框架。
- Spring Data Repositories:支持 JDBC、JPA、NoSQL 等数据库的数据仓库。
Spring MVC 架构基于 Servlet API 构建,采用同步阻塞 I/O 架构,每个请求占用一个线程,请求处理过程中线程会阻塞等待 I/O 操作完成。这样就是使用了传统的分时 CPU,适合小规模的普通应用,因为传统编程模型,是较为传统、开发者熟悉的编程模型,代码编写、阅读和调试相对容易,基于命令式编程。运行依赖 Servlet 容器,如 Tomcat、Jetty 等。
响应式栈处理高并发时,用少量线程和资源;Servlet 栈高并发下需较多线程,资源消耗大,线程池线程耗尽时性能受影响。响应式栈适合实时性要求高、高并发场景,如物联网、金融交易系统;Servlet 栈适合传统 Web 应用开发,对并发要求不是极高的场景 。
Spring Boot 概述
Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化 Spring 应用的创建、运行、调试、部署等。使用 Spring Boot 可以做到专注于 Spring 应用的开发,而无需过多关注 XML 的配置。Spring Boot 使用“习惯优于配置”的理念,简单来说,它提供了一堆依赖打包,并已经按照使用习惯解决了依赖问题。使用 Spring Boot 可以不用或者只需要很少的 Spring 配置就可以让企业项目快速运行起来。
- 提供预配置的依赖包
- 按照使用习惯解决依赖问题
- 极大减少XML配置
- 开箱即用的应用程序架构
SpringBoot是一个快速开发的框架,能过快速整合第三方框架,他是如何快速整合的呢?其实他是的基本原来是Maven依赖关系,Maven的集成,完全采用注解化,简化XML配置,内嵌HTTP服务器(Tomcate,jetty),默认嵌入Tomcate,最终以Java应用程序进行执行。
所以说,Spring Boot 是开发者和 Spring Framework 本身框架的中间层,帮助开发者统筹管理应用的配置,提供基于实际开发中常见配置的默认处理(即习惯优于配置),简化应用的开发,简化应用的运维;
总的来说,其目的 Spring Boot 就是为了对 Java web 的开发进行“简化”和加“快”速度,简化开发过程中引入或启动相关 Spring 功能的配置。这样带来的好处就是降低开发人员对于框架的关注点,可以把更多的精力放在自己的业务代码上。
同时随着微服务概念的推广和实践,Spring Boot 的精简理念又使其成为Java微服务开发的不二之选,也可以说,Spring Boot 其实就是为了微服务而生的 Java web 框架。
SpringBoot与SpringMVC 的区别是什么,说白了,就是 Spring Boot Web 组件默认集成 SpringMVC 框架, SpringMVC3.0 以后支持注解方式使用 java 代码启动 SpringMVC 。
与 Spring Framework衔接并且起步
我们已经在前面详细介绍了Spring框架,它的主要功能包括IoC容器、AOP支持、事务支持、MVC开发以及强大的第三方集成功能等。
那么,Spring Boot又是什么?它和Spring是什么关系?
Spring Boot是一个基于Spring的套件,它帮我们预组装了Spring的一系列组件,以便以尽可能少的代码和配置来开发基于Spring的Java应用程序。
如果把应用开发比作组装汽车:
- Spring Framework = 汽车零部件(发动机、传动、轮胎、底盘等)
- Spring Boot = 预装好的整车(可以直接上路,需要时可以换配件)
因此,Spring Boot和Spring的关系就是整车和零部件的关系,它们不是取代关系,试图跳过Spring直接学习Spring Boot是不可能的。
Spring Boot的目标就是提供一个开箱即用的应用程序架构,我们基于Spring Boot的预置结构继续开发,省时省力。
本章我们将详细介绍如何使用Spring Boot。
本教程使用的Spring Boot版本是3.x版,如果使用Spring Boot 2.x则需注意,两者有以下不同:
Spring Boot 2.x | Spring Boot 3.x | |
---|---|---|
Spring版本 | Spring 5.x | Spring 6.x |
JDK版本 | >= 1.8 | >= 17 |
Tomcat版本 | 9.x | 10.x |
Annotation包 | javax.annotation | jakarta.annotation |
Servlet包 | javax.servlet | jakarta.servlet |
JMS包 | javax.jms | jakarta.jms |
JavaMail包 | javax.mail | jakarta.mail |
Spring Boot 3.x的重要变化:
1 | // Spring Boot 2.x |
注意:Spring Boot 3.x要求JDK
17+,并且包名从javax.*
迁移到jakarta.*
如果使用Spring Boot的其他版本,则需要根据需要调整代码。
Spring Boot的核心功能(核心特性)
可独立运行的Spring项目:Spring Boot 可以以 jar 包的形式独立运行。
1
2# 直接运行jar包
java -jar myapp.jar内嵌的Servlet容器:Spring Boot可以选择内嵌 Tomcat、Jetty 或者 Undertow,无须以 war 包形式部署项目。
1
2
3
4
5
6
7# application.yml配置示例
server:
port: 8080
servlet:
context-path: /api
tomcat:
max-threads: 200简化的Maven配置:Spring 提供推荐的基础 pom.xml 文件来简化 Maven 配置。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19<!-- 父POM继承 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.0</version>
<relativePath/>
</parent>
<!-- Starter依赖 -->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
</dependencies>自动配置Spring以及第三方库:Spring Boot 会根据项目依赖来自动配置Spring 框架,极大地减少项目要使用的配置。也就是所谓的 约定大于配置
1
2
3
4
5
6
7
8
9
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
// @SpringBootApplication 等价于:
// @Configuration + @EnableAutoConfiguration + @ComponentScan提供生产级特性 Actuator :提供可以直接在生产环境中使用的功能,如性能指标、应用信息和应用健康检查。
1
2
3
4<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>常用监控端点:
/actuator/health
- 健康检查/actuator/metrics
- 性能指标/actuator/info
- 应用信息/actuator/env
- 环境配置
拥有可选的 starter:简化应用的整合,为生产的各种场景准备了对应的依赖坐标,导入一个就能全部导入
Starter依赖生态
Starter 名称 功能描述 spring-boot-starter-web
Web 开发(Spring MVC) spring-boot-starter-webflux
响应式 Web 开发 spring-boot-starter-data-jpa
JPA 数据访问 spring-boot-starter-security
Spring Security 安全 spring-boot-starter-test
测试支持 spring-boot-starter-redis
Redis 缓存 无代码生成和xml配置:Spring Boot 不生成代码。完全不需要任何 xml 配置即可实现 Spring 的所有配置。
传统Spring配置
1
2
3
4
5
6
7
8
9
10
11
12
13<!-- web.xml -->
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring-mvc.xml</param-value>
</init-param>
</servlet>
<!-- spring-mvc.xml -->
<context:component-scan base-package="com.example"/>
<mvc:annotation-driven/>Spring Boot配置:
1
2
3
4
5
6// 一个注解搞定!
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
快速整合原理
1 | <!-- Spring Boot的魔法:starter依赖 --> |
Spring Boot快速整合第三方框架的原理:
- Maven依赖管理:通过starter依赖自动引入相关组件
- 注解驱动:完全采用注解化配置,简化XML
- 内嵌服务器:默认嵌入Tomcat,支持Jetty、Undertow
- 自动配置:根据classpath自动配置组件
Spring Boot与微服务
Spring Boot的精简理念使其成为Java微服务开发的首选框架:
- 轻量级、快速启动
- 独立运行,无需外部容器
- 易于容器化部署
- 完美支持Cloud Native应用
建议学什么
以尚硅谷的为例子

Java 基础
- Java 基础:熟练掌握 Java 语法,包括面向对象编程(类、对象、继承、多态等 )、异常处理、泛型、集合框架等。同时,Java 17 及以上版本特性也需了解,因为 Spring Boot3 与 Java 17 及更高版本兼容。
- 函数式编程基础:理解 Lambda 表达式、函数式接口,Stream API 等函数式编程相关概念 ,这有助于理解和使用 Spring Boot3 中一些响应式编程和函数式风格的特性。
Spring Boot3 核心概念
- 自动配置:Spring Boot3 能根据项目依赖和配置自动配置应用,像自动配置 Web 服务器、数据库连接池、缓存等。需明白其自动配置原理和机制,以及如何自定义配置覆盖默认配置。
- 起步依赖:通过添加起步依赖(如 spring - boot - starter - web、spring - boot - starter - data - jpa 等),Spring Boot3 自动引入所需的其他依赖,要掌握常见起步依赖用途和使用场景。
- 嵌入式服务器:内置 Tomcat、Jetty、Undertow 等嵌入式服务器,了解如何配置和使用它们,以及不同服务器的特点和适用场景。
- Actuator:用于监控和管理 Spring Boot3 应用,提供健康检查、性能指标、环境信息等功能。学会使用 Actuator 暴露的端点监控应用运行状态。
配置相关
- 配置文件:掌握 application.properties 和 application.yml 两种配置文件语法格式,以及如何配置常见项,如日志、数据源、Web 服务器端口等。了解配置文件外部化、配置文件优先级等知识。
- 自定义配置与属性:学会通过 @Value 注解注入属性值,使用 @ConfigurationProperties 绑定配置属性到自定义类 。
Web 开发
- RESTful API 开发:利用 Spring MVC(Spring Boot3 默认 Web 框架 )创建 RESTful API,掌握 @RestController、@RequestMapping、@GetMapping 等常用注解,以及请求参数处理、响应数据格式化等。
- Thymeleaf 等模板引擎:若开发传统 Web 应用,了解 Thymeleaf 等模板引擎,用于渲染动态 HTML 页面。
数据访问
- JPA(Java Persistence API):使用 spring - boot - starter - data - jpa 起步依赖集成 JPA,掌握 JPA 基本操作,如实体类定义、Repository 接口编写、数据库 CRUD 操作。
- 其他数据访问技术:除 JPA 外,了解 Spring Data 对其他数据库(如 MySQL、PostgreSQL、Redis、MongoDB 等 )的支持和操作方式。
安全相关
- Spring Security:集成 Spring Security 实现用户认证和授权,掌握基本认证方式(如表单认证、HTTP Basic 认证 )、授权机制(如基于角色的访问控制 RBAC )、密码加密等。
响应式编程
- Reactor:理解响应式编程模型,掌握 Reactor 框架中 Mono(表示 0 或 1 个元素的异步序列 )和 Flux(表示 0 到多个元素的异步序列 )的使用,以及流操作符(如 map、filter、flatMap 等 )、线程调度、错误处理等。
- Spring WebFlux:基于 Reactor 的响应式 Web 框架,了解其与 Spring MVC 的区别,学会使用 Spring WebFlux 开发异步、非阻塞的 Web 应用,处理高并发场景。
- Spring Data R2DBC:用于响应式访问关系型数据库,掌握 R2dbc 驱动使用、DatabaseClient API 操作数据库,以及自定义 Repository、处理关联查询等。
- Spring Security Reactive:在响应式编程模型下实现安全控制,了解 RBAC 权限模型配置、FilterChain 配置、ReactiveUserDetailsService 等。
其他
- 项目构建与部署:掌握 Maven 或 Gradle 构建工具,学会打包项目(如生成可执行 JAR 或 WAR 包 )。了解项目在生产环境的部署方式,如容器化(Docker、Kubernetes )、负载均衡等。
- 性能优化与调优:掌握配置文件优化(如设置合理线程池、连接池 )、使用缓存(@Cacheable 注解 )、异步处理(@Async 注解 )等性能优化技巧。
- 日志管理:学会配置日志级别、输出格式等,使用日志记录应用运行信息,排查问题。
这一套方案的比较全面且比较基础的,Spring Boot3 还要很多别的东西
Spring Boot 官方文档:https://docs.spring.io/spring-boot/index.html
第一个 Spring Boot 程序
要了解Spring Boot,我们先来编写第一个Spring Boot应用程序,看看与前面我们编写的Spring应用程序有何异同。
目录结构
我们新建一个springboot-ergou
的工程,创建标准的 Maven工程
目录结构如下:
1 | springboot-demo/ |
在存放源码的src/main/java
目录中,Spring
Boot对Java包的层级结构有一个要求。注意到我们的根package是edu.software.ergoutree.springbootpritical
,下面还有其他子包。
但是,Spring
Boot要求main()
方法所在的启动类必须放到根package下,命名不做要求
依赖导入
我们再观察pom.xml
,它的内容如下
1 |
|
这其实 pom.xml 文件里面有几个 Spring Boot 开发的步骤
创建项目,就是导入spring-boot-starter-parent
继承
使用Spring
Boot时,强烈推荐从spring-boot-starter-parent
继承,因为这样就可以引入Spring
Boot的预置配置
1 | <!-- pom.xml --> |
- 统一依赖版本:内置了所有 Spring Boot 依赖的版本号(称为 “BOM”,Bill of Materials),避免依赖冲突。
- 简化配置:提供默认的插件配置(如编译版本、资源过滤等)。引入依赖时无需写
version
(除非需要覆盖默认版本)。
紧接着,我们引入了其他依赖,可发现无需指定版本号,因为引入的
<parent>
内已经指定了,只有我们自己引入的某些第三方jar包需要指定版本号。
导入场景
就是导入各种场景启动器
1 | <!--web开发的场景启动器,嵌入了 Tomcat--> |
打包
1 | <!-- Spring Boot应用打包插件,项目构建配置 --> |
$ mvn clean package
把项目打成可执行的 jar 包
java -jar 包名.jar
启动项目
主程序启动类
1 | package edu.software.ergoutree.springbootpritical; |
启动Spring
Boot应用程序只需要一行代码加上一个注解@SpringBootApplication
,该注解实际上又包含了:
- @SpringBootConfiguration
- @Configuration
- @EnableAutoConfiguration
- @AutoConfigurationPackage
- @ComponentScan
这样一个注解就相当于启动了自动配置和自动扫描。
配置文件的异同
1 | server: |
1 | spring.application.name=SpringBootPritical |
可见,YAML是一种层级格式,它和.properties
很容易互相转换,它的优点是去掉了大量重复的前缀,并且更加易读。
而在配置文件中,我们经常使用如下的格式对某个key进行配置:
1 | logging: |
${变量名:默认值}
语法的核心逻辑
这种${DB_HOST:localhost}
意思是,首先从环境变量查找DB_HOST
,如果环境变量定义了,那么使用环境变量的值,否则,使用默认值localhost
。
这种语法的执行逻辑如下:
- 优先查找环境变量:Spring Boot
会首先检查操作系统环境变量中是否存在
DB_HOST
- 其次查找系统属性:若环境变量不存在,会检查 Java
系统属性(如通过
-DDB_HOST=xxx
设置) - 最后使用默认值:若前两者均不存在,则使用
:
, 后的默认值localhost
这使得我们在开发和部署时更加方便,因为开发时无需设定任何环境变量,直接使用默认值即本地数据库,而实际线上运行的时候,只需要传入环境变量即可,而且做到了配置与代码分离,避免敏感信息的直接显式暴露
Spring Boot 对环境变量的解析机制
- 变量解析顺序(优先级从高到低):
- 命令行参数(如
--db.host=xxx
) - 操作系统环境变量
application-{profile}.yml
配置文件application.yml
配置文件- 代码中硬编码的默认值
- 命令行参数(如
- 复杂变量场景
- 多层级变量:
${APP_CONFIG.db.host}
- 必选变量(无默认值):
${REQUIRED_VAR}
(若不存在则启动报错) - 组合变量:
${DB_HOST}:${DB_PORT}
- 多层级变量:
业务部分,以Controller为例子
实际上其他包也都是一回事,这里就拿 Controller 说了
使用 REST API 的 Controller 如下
1 | package edu.software.ergoutree.springbootpritical.controller; |
测试
在 test 文件夹下编写测试类就行,在这里会有一些特殊的注解
启动
Spring
Boot自动启动了嵌入式Tomcat,当看到Started Application in xxx seconds
时,Spring
Boot应用启动成功。
现在,我们在浏览器输入localhost:8080
就可以直接访问页面。那么问题来了:
前面我们定义的数据源、声明式事务、JdbcTemplate在哪创建的?怎么就可以直接注入到自己编写的UserService
中呢?
这些自动创建的Bean就是Spring Boot的特色:AutoConfiguration。
当我们引入spring-boot-starter-jdbc
时,启动时会自动扫描所有的XxxAutoConfiguration
:
DataSourceAutoConfiguration
:自动创建一个DataSource
,其中配置项从application.yml
的spring.datasource
读取;DataSourceTransactionManagerAutoConfiguration
:自动创建了一个基于JDBC的事务管理器;JdbcTemplateAutoConfiguration
:自动创建了一个JdbcTemplate
。
因此,我们自动得到了一个DataSource
、一个DataSourceTransactionManager
和一个JdbcTemplate
。
类似的,当我们引入spring-boot-starter-web
时,自动创建了:
ServletWebServerFactoryAutoConfiguration
:自动创建一个嵌入式Web服务器,默认是Tomcat;DispatcherServletAutoConfiguration
:自动创建一个DispatcherServlet
;HttpEncodingAutoConfiguration
:自动创建一个CharacterEncodingFilter
;WebMvcAutoConfiguration
:自动创建若干与MVC相关的Bean。- …
引入第三方pebble-spring-boot-starter
时,自动创建了:
PebbleAutoConfiguration
:自动创建了一个PebbleViewResolver
。
Spring
Boot大量使用XxxAutoConfiguration
来使得许多组件被自动化配置并创建,而这些创建过程又大量使用了Spring的Conditional功能。例如,我们观察JdbcTemplateAutoConfiguration
,它的代码如下:
1 |
|
当满足条件:
@ConditionalOnClass
:在classpath中能找到DataSource
和JdbcTemplate
;@ConditionalOnSingleCandidate(DataSource.class)
:在当前Bean的定义中能找到唯一的DataSource
;
该JdbcTemplateAutoConfiguration
就会起作用。实际创建由导入的JdbcTemplateConfiguration
完成:
1 |
|
创建JdbcTemplate
之前,要满足@ConditionalOnMissingBean(JdbcOperations.class)
,即不存在JdbcOperations
的Bean。
可见,Spring
Boot自动装配功能是通过自动扫描+条件装配实现的,这一套机制在默认情况下工作得很好,但是,如果我们要手动控制某个Bean的创建,就需要详细地了解Spring
Boot自动创建的原理,很多时候还要跟踪XxxAutoConfiguration
,以便设定条件使得某个Bean不会被自动创建。
使用开发者工具
在开发阶段,我们经常要修改代码,然后重启Spring Boot应用。经常手动停止再启动,比较麻烦。
Spring Boot提供了一个开发者工具,可以监控classpath路径上的文件。只要源码或配置文件发生修改,Spring Boot应用可以自动重启。在开发阶段,这个功能比较有用。
要使用这一开发者功能,我们只需添加如下依赖到pom.xml
:
1 | <dependency> |
然后,没有然后了。直接启动应用程序,然后试着修改源码,保存,观察日志输出,Spring Boot会自动重新加载。
默认配置下,针对/static
、/public
和/templates
目录中的文件修改,不会自动重启,因为禁用缓存后,这些文件的修改可以实时更新。
简单打包 Spring Boot
普通的 Java 程序,使用
maven-shade-plugin
就可以打包一个可执行的 jar 包
在Spring Boot应用中,打包更加简单,当然如果你只是打 jar
包,因为Spring
Boot自带一个更简单的spring-boot-maven-plugin
插件用来打包,我们只需要在pom.xml
中加入以下配置
1 | <project ...> |
无需任何配置,Spring Boot的这款插件会自动定位应用程序的入口Class,我们执行Maven的打包命令即可打包:
1 | $ mvn clean package |
打包后我们在target
目录下可以看到两个jar文件:
以springboot-exec-jar
项目为例
其中,springboot-exec-jar-1.0-SNAPSHOT.jar.original
是Maven标准打包插件打的jar包,它只包含我们自己的Class,不包含依赖,而springboot-exec-jar-1.0-SNAPSHOT.jar
是Spring
Boot打包插件创建的包含依赖的jar,可以直接运行
这样,部署一个Spring Boot应用就非常简单,无需预装任何服务器,只需要上传jar包即可。
在打包的时候,因为打包后的Spring
Boot应用不会被修改,因此,默认情况下,spring-boot-devtools
这个依赖不会被打包进去。但是要注意,使用早期的Spring
Boot版本时,需要配置一下才能排除spring-boot-devtools
这个依赖
特性小结
简化整合
导入相关的场景,就拥有了相关的功能,也就是场景启动器
Spring Boot官方默认支持很多 starter,amqp,aop,jdbc,jpa什么的都有,都叫
spring-boot-starter
第三方还要各种场景启动器的提供,命名为
*-spring-boot-starter
简化开发
简化配置
application.properties
:集中式管理配置,只需要修改这个文件就行,而且配置基本都有默认值简化部署
都嫩打包为可执行的 jar 包,linux 服务器上有 java 环境就能运行
简化运维
修改配置(外部放一个
application.properties
),监控应用,健康检查
Spring Boot Initializer
Spring Boot 创建项目的初始化向导,简化初始化项目

下面就是选场景,选依赖
