文章目录
- [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 官网 :点此进入
一、概述
-
Spring Boot 核心思想:约定大于配置;
-
Spring Boot 的主要优点:
- 为所有 Spring 开发者更快地入门;
- 开箱即用 ,提供各种默认配置来简化项目配置;
- 内嵌式容器简化 Web 项目;
- 没有冗余代码生成和 XML 配置的要求。
-
单体应用架构(all in one)
- 是指一个应用中的所有功能单元都封装在一个应用中,例如将数据库访问、Web 访问等各个功能都放到一个 war 包内;
- 优点:易于开发和测试,方便部署,当需要扩展时,将 war 包复制多份,然后放在多个服务器上,再做个负载均衡即可;
- 缺点:如果要修改某处,必须停掉整个服务,重新打包部署,并且对于大型应用,不可能把所有内容都放在一个应用中。
-
微服务架构
- 把每个功能元素独立出来,然后将独立的功能元素动态组合,微服务架构是对功能元素进行复制,而没有对整个应用进行复制;
- 优点 :节省了调用资源,并且每个功能元素都是一个可替换的、可独立升级的软件代码(高内聚,低耦合)。
- 微服务的具体阐述,中文翻译 :点此进入;
- 微服务架构 中,各个功能元素完成自己的功能,然后通过 http 相互请求调用。例如 一个电商系统中,查缓存、连接数据库、结账、支付等服务都是一个个独立的功能元素,它们作为一个个微服务共同构建了一个庞大的系统,如果要修改其中的一个功能,只需要升级其中一个功能服务单元即可;
- Spring 为构建实现微服务,提供了从构建应用单元到完成大型分布式应用的方案 :
- 使用 Spring Boot 可以构建一个个功能独立的微服务应用单元;
- 使用 Spring Cloud 可以实现分布式,完成大型分布式网络服务的调用;
- 使用 Spring Cloud Data Flow 可以在分布式中间进行流式数据计算 、批处理等。
二、第一个 Spring Boot 程序
步骤
运行报错的情况:
如果运行报错 :类文件具有错误的版本 61.0,应为 52.0,此时需要在 pom.xml 中降低 Spring Boot 的版本,这里降为 2.7.12;
如果运行报错:java 无效的目标发行版:17,此时需要修改两个地方,如图所示:
- 打开 Settings 设置,修改 Java 编译器的版本为 1.8;
- 打开项目结构,修改 Sources 和 Dependencies 为 1.8。
运行成功,并添加 controller 文件夹
说明:
- 程序主入口所在的类由注解 @SpringBootApplication 声明,查看源码,发现该类是 Spring 的一个组件(@Component);
- controller 包一定要与程序主入口所在的类在同级目录;
- Spring Boot 使用 Tomcat 作为默认嵌入式容器;
- 通过查看 pom.xml 文件,可以看到有一个父项目:spring-boot-starter-parent;
- 所有的 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: [小张, 小明] # 行内写法
注意:
- 字符串不一定要用双引号标识;
- 在缩排中空白字符的数目并不是非常重要,只要相同阶层的元素左侧对齐 就可以(注意不能使用 Tab 字符);
- 允许选择性加入空行,以增加可读性;
- 在 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 方法来实现依赖注入。
- 原因 :在自动生成 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 方法 :获取自动配置类,遍历,封装。
- 调用 SpringFactoriesLoader 类中的 loadFactoryNames 方法 :获取所有(主启动类)的加载配置;
- getCandidateConfigurations 方法 :获取候选的配置 configurations;
- @AutoConfigurationPackage
过程:
- Spring Boot 在启动时,从类路径
spring-boot-autoconfigure-2.7.12.jar/META-INF/spring.factories
下获取指定的值; - 在
spring.factories
中,所有的组件以类名的方式返回 ,将这些自动配置的类导入容器 ,自动配置就会生效; - 有些自动配置类会被注解
@ConditionalOnxxx
声明,表示如果条件都满足,该自动配置类才会生效; - 之前我们需要手动配置的东西,现在 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 类主要做了以下四个事情:
- 推断应用的类型是普通项目还是 Web 项目;
- 查找并加载所有可用初始化器,设置到 initializers 属性中;
- 找出所有的应用程序监听器,设置到 listeners 属性中;
- 推断并设置 main 方法的定义类,找到运行的主类。
注意:
- 有目标,持续学习,不断进步!
- Spring Boot 官网:https://spring.io/projects/spring-boot#overview
- 微服务的具体阐述,中文翻译链接:https://www.cnblogs.com/liuning8023/p/4493156.html
- Spring Boot 自定义启动 Banner 在线生成工具:https://www.bootschool.net/ascii