1. SpringBoot2 简介
Spring生态包含了各种各样的功能,覆盖了web开发、数据访问、安全控制、分布式、消息服务、移动开发等等。
SpringBoot官方的解释是能快速创建出生产级别的Spring应用:
Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can “just run”.
由于 Spring5 的重大升级:响应式编程,让SpringBoot也进行了版本更迭

基于Java8的一些新特性,如:接口默认实现。重新设计源码架构。
SpringBoot优点
- Create stand-alone Spring applications
- 创建独立Spring应用
- Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
- 内嵌web服务器
- Provide opinionated ‘starter’ dependencies to simplify your build configuration
- 自动starter依赖,简化构建配置
- Automatically configure Spring and 3rd party libraries whenever possible
- 自动配置Spring以及第三方功能
- Provide production-ready features such as metrics, health checks, and externalized configuration
- 提供生产级别的监控、健康检查及外部化配置
- Absolutely no code generation and no requirement for XML configuration
- 无代码生成、无需编写XML
缺点:迭代快,需要时刻关注变化,另外封装太深,内部原理复杂,不容易精通
微服务
- 微服务是一种架构风格
- 一个应用拆分为一组小型服务
- 每个服务运行在自己的进程内,也就是可独立部署和升级
- 服务之间使用轻量级HTTP交互
- 服务围绕业务功能拆分
- 可以由全自动部署机制独立部署
- 去中心化,服务自治。服务可以使用不同的语言、不同的存储技术
分布式
不同的业务模块部署在不同的服务器上或者同一个业务模块分拆多个子业务,部署在不同的服务器上,解决高并发的问题,提供可扩展性以及高可用性,业务中使用分布式的场景主要有分布式存储以及分布式计算。分布式存储中可以将数据分片到多个节点上,不仅可以提高性能(可扩展性),同时也可以使用多个节点对同一份数据进行备份。
分布式的困难:远程调用、服务发现、负载均衡、服务容错、配置管理、服务监控、链路追踪、日志管理、任务调度…
解决:
- SpringBoot + SpringCloud
云原生
Cloud Native
云原生是一种构建和运行应用程序的方法,是一套技术体系和方法论。
上云的困难:服务自愈、弹性伸缩、服务隔离、自动化部署、灰度发布、流量治理…
解决:DevOps+持续交付+微服务+容器
2. 快速入门
HelloWorld
SpringBoot2系统要求:
- Java 8 & 兼容java14 .
- Maven 3.3+
根据SpringBoot(2.7.6)官方文档的 Getting Satrted 我们可以上手第一个程序
创建好 Maven 工程后,添加依赖:
1 | <parent> |
我们即可写业务程序,官方模板:
1 | //相当于 @ResponseBody + @Controller |
官方对于第二条注释的解释:
这个注释告诉SpringBoot根据您添加的jar依赖项“猜测”您希望如何配置Spring。由于spring-boot-starter-web添加了Tomcat和SpringMVC,所以自动配置假设您正在开发一个web应用程序,并相应地设置spring。
拆分为两个类
1 | //主程序类 |
直接运行 main 方法即可
简化配置
application.properties
SpringBoot 的一切配置都可以写在此文件中,SpringBoot 会自动解析
简化部署
SpringBoot 官方文档中写明 Creating an Executable Jar(创建可执行Jar)
添加插件:
1 | <build> |
该插件可以不通过 Tomcat 直接运行 jar 包(注意不是 war 包)
生成的 jar 包中有 Tomcat 的核心API

关闭命令行项目就会停止运行
3. 自动配置原理
SpringBoot特点
依赖管理
- 父项目做依赖管理
1 | <!-- 导入的父项目:--> |
- 开发导入starter场景启动器
官方解释:Starters是一组方便的依赖描述符,可以包含在应用程序中。
官方都遵循类似的命名模式;spring-boot-starter-*,其中*是特定类型的应用程序。*-spring-boot-starter: 第三方为我们提供的简化开发的场景启动器。
只要引入starter,这个场景的所有常规需要的依赖我们都自动引入。
1 | <!-- 所有场景启动器都有最底层的依赖:--> |
- 无需关注版本号,自动版本仲裁
- 引入依赖默认都可以不写版本
- 引入非版本仲裁的jar,要写版本号。
- 可以修改默认版本号
1 | 查看spring-boot-dependencies中规定当前依赖的版本用的 key。 |
自动配置
自动配好Tomcat
- 引入Tomcat依赖。
- 配置Tomcat
自动配好SpringMVC
- 引入SpringMVC全套组件
- 自动配好SpringMVC常用组件(功能)
自动配好Web常见功能,如:字符编码问题
默认的包结构
- 主程序所在包及其下面的所有子包里面的组件都会被默认扫描
- @SpringBootApplication(scanBasePackages=”com”)或者@ComponentScan 可以指定扫描路径
1 |
|
- 各种配置拥有默认值
- 默认配置最终都是映射到某个类上,如:MultipartProperties
- 配置文件的值最终会绑定每个类上,这个类会在容器中创建对象
- 按需加载所有自动配置项
- 引入了哪些场景这个场景的自动配置才会开启
- SpringBoot所有的自动配置功能都在 spring-boot-autoconfigure 包里面
可以通过 SpringApplication 查看容器中的 bean
1 | ConfigurableApplicationContext run = SpringApplication.run(MyApplication.class, args); |
容器功能
组件添加
@Configuration
基本使用:
- 配置类里面使用@Bean标注在方法上给容器注册组件,默认也是单实例的;
- 配置类本身也是组件
- proxyBeanMethods:代理bean的方法
- Full(proxyBeanMethods = true)、【返回的组件都是单实例的】
- Lite(proxyBeanMethods = false)【返回的组件都是新创建的】
- 组件依赖必须使用Full模式(默认)。其他看情况使用Lite模式
因为不需要扫描容器,直接调用方法,所以称为 Lite,运行更快
1 | //告诉SpringBoot这是一个配置类 == 配置文件 |
@Bean、@Component、@Controller、@Service、@Repository、@ComponentScan
这些在Spring框架中都有介绍
@Import
1 | //通过空参构造器给容器中自动创建出这两个类型的组件 |
@Import 高级用法: https://www.bilibili.com/video/BV1gW411W7wy?p=8
@Conditional
条件装配:满足Conditional指定的条件,则进行组件注入。
SpringBoot 底层的自动装配大量使用了该注解

1 | //当容器中没有名为 tom 的组件时将类中的组件注入容器 |
@ImportResource
该注解可以引入原生的Spring配置文件
1 |
|
配置绑定
最初我们读取properties文件中的内容比较复杂:
1 | Properties pps = new Properties(); |
@ConfigurationProperties
1 | person.name=张三 |
1 | //只有在容器才会拥有SpringBoot提供的强大功能 |
@EnableConfigurationProperties
1 |
|
@EnableConfigurationProperties + @ConfigurationProperties 的作用和 @Component + @ConfigurationProperties 是相同的
自动配置原理
引导加载自动配置类
在介绍 @SpringBootConfiguration 时,有一个未曾谋面的注解:
@EnableAutoConfiguration
1 |
|
@AutoConfigurationPackage
指定了默认的包规则
1 |
|
利用Registrar给容器中导入一系列组件;将指定的一个包下的所有组件导入,默认是声明 @SpringBootApplication 所在包
AutoConfigurationImportSelector.class
SpringBoot 一直在更新迭代,不同小版本的结构可能不尽相同,但大致思路不会发生大的改变
1 | protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) { |
这个方法中会给容器批量导入一些组件。其中 configurations 中存储着所有需要导入到容器的配置类:
1 | protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { |
利用工厂加载
Map<String, List<String>> loadSpringFactories(ClassLoader classLoader);得到所有的组件
看字符串即可知道会查询所有的 META-INF/spring.factories 和 META … imports 文件,在2.3.4版本中配置类就放在spring-boot-autoconfigure-2.3.4.RELEASE.jar/META-INF/spring.factories,打断点或配置文件中可以看到有127个;我使用的2.7.6版本中有144个,放在 META … imports中。
按需开启自动配置项
虽然SpringBoot中的配置文件中写死了启动时要给容器加载的所有配置类;但 xxxxAutoConfiguration 按照条件装配规则(@Conditional),最终会按需配置。
在引导自动装配时也会过滤掉没有成功装配的类,最终容器中的类取决于导入的依赖
修改配置项


SpringBoot 帮我们配置好了DispatcherServlet:
1 |
|
顺便还帮我们配置了文件上传组件:其中给@Bean标注的方法传入了对象参数,帮我们重命名(方法名),防止有些用户配置的文件上传解析器不符合规范,
如果我们不进行配置,SpringBoot默认会在底层配置好所有的组件(@ConditionalOnMissingBean)
定制化配置:
- 直接自己@Bean替换底层的组件
- 看这个组件获取配置文件的值后在 application 中修改
1 | xxxxxAutoConfiguration ---> 组件 ---> xxxxProperties里面拿值 ----> application.properties |
在官方文档中也可以查看能修改的参数:Common Application Properties (spring.io)
开发插件
Lombok
直接在 父pom 中查找即可:
1 | <dependency> |
LomBok 插件可以简化 JavaBean 的开发:
- @NoArgsConstructor:编译时创建无参构造器
- @AllArgsConstructor:编译时创建全参构造器
- @RequiredArgsConstructor : 生成一个包含 “特定参数” 的构造器,特定参数指的是带有 final 修饰词或带有@NonNull注解的变量们
其余数量的构造器得自己创建
- @Data:编译时创建所有JavaBean方法
@Data 这个注解,等于同时加了@Getter/@Setter、@ToString、@EqualsAndHashCode、@RequiredArgsConstructor
- @ToString:编译时创建 ToString 方法
- @EqualsAndHashCode:编译时创建 equals 和 HashCode 方法
- @NotNull:用在成员方法或者构造方法的参数上,会自动产生一个关于此参数的非空检查,如果参数为空,则抛出一个空指针异常。
流式写法
- @Accessors:实现链式开发,set方法返回的是对象
注解属性:
- fluent 属性 : 链式的形式,默认为false,当该值为 true 时,对应字段的 getter 方法前面就没有 get,setter 方法就不会有 set。
- chain 属性 : 流式的形式,set方法返回当前对象。
- prefix 属性 : 生成指定前缀的属性的getter与setter方法,并且生成的getter与setter方法时会去除前缀
- @Builder
@Builder提供了一种比较推崇的构建值对象的方式;缺点就是父类的属性不能产于builder。
原代码:
1 |
|
编译后:
1 | public class Demo { |
简化日志
1 |
|
applicaton.properties 中 debug=true 开启日志服务
DevTools
1 | <dependency> |
项目或者页面修改后直接编译就可以生效:Ctrl+F9
Spring Initailizr
项目初始化向导

在选择好开发场景后,idea会自动帮我们引入依赖、创建项目结构、编写主配置类(@SpringBootApplication)
4. 核心功能

5. 单元测试
Spring Boot 2.2.0 版本开始引入 JUnit 5 作为单元测试默认库
JUnit5与之前版本的Junit框架有很大的不同,由三个不同子项目的几个不同模块组成。
JUnit 5 = JUnit Platform + JUnit Jupiter + JUnit Vintage
Junit Platform是在JVM上启动测试框架的基础,不仅支持Junit自制的测试引擎,其他测试引擎也都可以接入。
JUnit Jupiter提供了JUnit5的新的编程模型,是JUnit5新特性的核心。内部包含了一个测试引擎,用于在Junit Platform上运行。
为了照顾老的项目,JUnit Vintage提供了兼容JUnit4.x,Junit3.x的测试引擎。
SpringBoot 2.4 以上版本移除了默认对 Vintage 的依赖。如果需要兼容junit4需要自行引入 vintage
1 | <dependency> |
使用:
1 |
|
具有Spring的功能,如@Transactional 标注测试方法,测试完成后自动回滚
以前:@SpringBootTest + @RunWith(SpringTest.class)
常用注解
JUnit5的注解与JUnit4的注解有所变化
官方手册:JUnit 5 User Guide
- @Test :表示方法是测试方法。与JUnit4的@Test不同,其不能声明任何属性,拓展的测试将会由Jupiter提供额外测试
- @ParameterizedTest :表示方法是参数化测试,下方会有详细介绍
- @RepeatedTest :表示方法可重复执行,下方会有详细介绍
- @DisplayName :为测试类或者测试方法设置展示名称
- @BeforeEach :表示在每个单元测试之前执行
- @AfterEach :表示在每个单元测试之后执行
- @BeforeAll :表示在所有单元测试之前执行
- @AfterAll :表示在所有单元测试之后执行
- @Tag :表示单元测试类别,类似于JUnit4中的@Categories
- @Disabled :表示测试类或测试方法不执行,类似于JUnit4中的@Ignore
- @Timeout :表示测试方法运行如果超过了指定时间将会返回错误
- @ExtendWith :为测试类或测试方法提供扩展类引用
断言
断言(assertions)是测试方法中的核心部分,用来对测试需要满足的条件进行验证。这些断言方法都是 org.junit.jupiter.api.Assertions 的静态方法。
检查业务逻辑返回的数据是否合理。所有的测试运行结束以后,会有一个详细的测试报告;
简单断言
用来对单个值进行简单的验证。
| 方法 | 说明 |
|---|---|
| assertEquals | 判断两个对象或两个原始类型是否相等 |
| assertNotEquals | 判断两个对象或两个原始类型是否不相等 |
| assertSame | 判断两个对象引用是否指向同一个对象 |
| assertNotSame | 判断两个对象引用是否指向不同的对象 |
| assertTrue | 判断给定的布尔值是否为 true |
| assertFalse | 判断给定的布尔值是否为 false |
| assertNull | 判断给定的对象引用是否为 null |
| assertNotNull | 判断给定的对象引用是否不为 null |
6. 配置文件
springboot支持的配置文件后缀有:.properties 和 .yaml 和.yml
这三个配置文件默认的优先级是:.properties > .yml > .yaml
springboot默认读取配置文件的位置有四个:
- 项目根目录/config 目录下
- 项目根目录下
- 类路径/config目录下:classpath:config/application.yml
- 类路径下:classpath: (idea默认生成的配置文件存储位置就是类路径下)
这四个配置文件的优先级:从上往下递减
如果有多个配置文件存在,相同的配置以优先级高的配置文件为准,不同的配置则各个配置文件成互补状态存在
多环境开发配置
方法1:
将多套配置都放在一个配置文件中application.yml中 ,一个配置文件中配置多套环境,环境之间使用---分割开
示例:
1 | #通用配置 ,设置启用那种环境以及编写一些公共的配置 |
这样配置之后,需要启用哪种环境来运行springboot的时候,只需要改通用配置中的active属性即可
方法2:
springboot允许通过命名约定按照一定的格式application-{profile}.properties来定义多个配置文件,然后通过在application.properyies通过spring.profiles.active来具体激活一个或者多个配置文件,如果没有没有指定任何profile的配置文件,默认使用application.properties。
可以在项目全局配置文件中配置spring.profile.active属性激活配置:
1 | #激活开发环境配置文件 |
除了可以用profile的配置文件来分区配置我们的环境变量,在代码里,我们还可以直接用@Profile注解来进行配置通过在配置文件激活具体使用哪个实现类。
推荐方式:
进入edit configurations -> modify options -> add vm options;在栏中添加:-Dspring.profiles.active=dev