SpringBoot详解1:核心技术
1、Spring Boot简介
1.1、回顾什么是Spring
Spring
是一个开源框架,2003
年兴起的一个轻量级的Java
开发框架,作者:Rod Johnson
(音乐学博士)。
Spring是为了解决企业级应用开发的复杂性而创建的,简化开发。
1.2、Spring是如何简化Java开发的
为了降低Java
开发的复杂性,Spring
采用了以下4种关键策略:
1、基于POJO
的轻量级和最小侵入性编程,所有东西都是bean
;
2、通过IOC
,依赖注入(DI
)和面向接口实现松耦合;
3、基于切面(AOP
)和惯例进行声明式编程;
4、通过切面和模版减少样式代码,RedisTemplate
,xxxTemplate
。
1.3、什么是Spring Boot
学过javaweb
的同学就知道:开发一个web
应用,从最初开始接触Servlet
结合Tomcat
,跑出一个Hello Wolrld
程序,是要经历特别多的步骤;后来就用了框架Struts
,再后来是SpringMVC
,到了现在的Spring Boot
,过一两年又会有其他web
框架出现;你们有经历过框架不断的演进,然后自己开发项目所有的技术也在不断的变化、改造吗?建议都可以去经历一遍。
言归正传,什么是Spring Boot
呢?就是一个javaweb
的开发框架,和SpringMVC
类似,对比其他javaweb
框架的好处,官方说是简化开发,约定大于配置,you can "just run"
,能迅速的开发web
应用,几行代码开发一个http
接口。
所有的技术框架的发展似乎都遵循了一条主线规律:从一个复杂应用场景衍生一种规范框架,人们只需要进行各种配置而不需要自己去实现它,这时候强大的配置功能成了优点;发展到一定程度之后,人们根据实际生产应用情况,选取其中实用功能和设计精华,重构出一些轻量级的框架;之后为了提高开发效率,嫌弃原先的各类配置过于麻烦,于是开始提倡“约定大于配置”,进而衍生出一些一站式的解决方案。
是的,这就是Java
企业级应用→J2EE
→spring
→Spring Boot
的过程。
随着Spring
不断的发展,涉及的领域越来越多,项目整合开发需要配合各种各样的文件,慢慢变得不那么易用简单,违背了最初的理念,甚至人称配置地狱。Spring Boot
正是在这样的一个背景下被抽象出来的开发框架,目的为了让大家更容易的使用Spring
、更容易的集成各种常用的中间件、开源软件。
Spring Boot
基于Spring
开发,SpirngBoot
本身并不提供Spring
框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于Spring
框架的应用程序。也就是说,它并不是用来替代Spring
的解决方案,而是和Spring
框架紧密结合用于提升Spring
开发者体验的工具。Spring Boot
以约定大于配置的核心思想,默认帮我们进行了很多设置,多数Spring Boot
应用只需要很少的Spring
配置。同时它集成了大量常用的第三方库配置(例如Redis
、MongoDB
、Jpa
、RabbitMQ
、Quartz
等等),Spring Boot
应用中这些第三方库几乎可以零配置的开箱即用。
简单来说就是Spring Boot
其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven
整合了所有的jar
包,Spring Boot
整合了所有的框架 。
Spring Boot
出生名门,从一开始就站在一个比较高的起点,又经过这几年的发展,生态足够完善,Spring Boot
已经当之无愧成为 Java
领域最热门的技术。
1.4、Spring Boot的主要优点
- 为所有
Spring
开发者更快的入门; - 开箱即用,提供各种默认配置来简化项目配置;
- 内嵌式容器简化Web项目;
- 没有冗余代码生成和XML配置的要求。
2、微服务架构
2.1、什么是微服务
微服务是一种架构风格。它要求我们在开发一个应用的时候,这个应用必须构建成一系列小服务的组合;可以通过http
等方式进行互通。
2.2、单体应用架构
要说微服务架构,先得说说过去的单体应用架构。
所谓“单体应用架构(all in one
)”是指:我们将一个应用中的所有应用服务都封装在一个应用中。无论是ERP
、CRM
或其它系统,我们都把数据库访问、Web
访问等功能放在一个war
包内。
all in one
的架构方式,我们把所有的功能单元放在一个应用里面,然后把整个应用部署到服务器上。如果负载能力不行,我们将整个应用进行水平复制,进行扩展,然后再负载均衡。
- 这样做的好处是:易于开发和测试;方便部署;当需要扩展时,只需将
war
包复制多份,然后放到多个服务器上,再做个负载均衡就可以了。 - 单体应用架构的缺点是:哪怕要修改一个非常小的地方,我们都要停掉整个服务,重新打包、部署整个应用的
war
包。特别是对于一个大型应用,我们不可能把所有内容放在一个应用里面,我们如何维护、如何分工合作都是问题。
2.3、微服务架构
所谓“微服务架构”,就是打破之前“all in one
”的架构方式,把每一个功能元素独立出来。把独立出来的功能元素动态组合,需要的功能元素才拿来组合,需要多一些时可以整合多个功能元素。所以,微服务架构是对功能元素进行复制,而没有对整个应用进行复制。
这样做的好处是:
- 节省了调度资源。
- 每个功能元素的服务都是一个可替换的、可独立升级的软件代码。
注:Martin Fowler
于2014年3月25日写的《Microservice
》,详细阐述了什么是微服务。
2.4、如何构建微服务
一个大型系统的微服务架构,就像一个复杂交织的神经网络,每一个神经元就是一个功能元素,它们各自完成自己的功能,然后通过http
互相请求调用。比如一个电商系统,查缓存、连接数据库、浏览页面、结账、支付等服务都是一个个独立的功能服务,它们都被微服务化了,它们作为一个个微服务共同构建了一个庞大的系统。如果修改其中的一个功能,只需更新升级其中的一个功能服务单元即可。
但是这种庞大的系统架构给部署和运维带来了很大的难度。于是,Spring
为我们带来了构建大型分布式微服务的全套产品,主要包括:
- 构建一个个功能独立的微服务应用单元,可以使用
Spring Boot
,它可以帮助我们快速构建一个应用(微服务)。 - 大型分布式网络服务的调用,这部分由
Spring Cloud
来完成,实现分布式。 - 在分布式中间,进行流式数据计算、批处理,我们有
Spring cloud data flow
。 Spring
为我们想清楚了整个从开始构建应用到大型分布式应用的全流程方案。
3、第一个Spring Boot应用程序
我们将学习如何快速的创建一个Spring Boot
应用,并且实现一个简单的Http
请求处理。通过这个例子对Spring Boot
有一个初步的了解,并体验其结构简单、开发快速的特性。
3.1、准备工作
(1)环境准备:
-
java version "1.8.0_181"
-
Maven-3.6.1
-
Spring Boot 2.7.7
注:
Spring Boot 3.0
以上版本最低支持Java 17
。 -
MySQL 5.7.19
(2)开发工具:
IDEA 2020.2
3.2、创建Spring Boot项目的两种方式
附:创建基础项目说明
Spring
官方为我们提供了一个快速构建(初始化)应用的网站Spring Initializr
:https://start.spring.io/IDEA
集成了这个网站!
3.2.1、方式1:使用Spring Initializr创建项目
主要步骤如下:
(1)打开 https://start.spring.io/
(2)填写项目信息。
(3)点击”Generate Project
“按钮生成项目、下载项目。
(4)解压项目包,并用IDEA
以Maven
项目导入,一路下一步即可,直到项目导入完毕。
**注:**如果是第一次使用,可能速度会比较慢,包比较多、需要耐心等待一切就绪。
3.2.2、方式2:使用IDEA创建项目(推荐)
主要步骤如下:
(1)点击File
→New
→Project
菜单,创建一个新的Spring Initializr
项目。
注:IDEA
默认去Spring
官网的快速构建工具那里下载项目文件。
(2)填写项目信息。项目名称为springboot-01-helloworld
。
(3)选择初始化的组件(初学勾选Spring Web
即可)和Spring Boot
的版本(我们这里选择2.7.7版)。
注:Spring Boot 3.0
以上版本最低支持 Java 17
。
(4)填写项目路径。
(5)等待项目构建成功即可。
附1:配置本地Maven
Spring Boot
项目创建过程中,可能会出现IDEA
的本地Maven
仓库配置不正确的问题。错误如下图所示:
此时,我们需要将Maven
设置成我们自己的Maven
,具体实现步骤如下:
-
先删除
IDEA
自动生成的.mvn
文件夹、.gitignore
、HELP.md
、mvnw
、mvnw.cmd
文件。如下图所示:注:
-
我们必须将
.mvn/wrapper/maven-wrapper.jar
删除,否则我们无法我们自己的Maven
安装目录。 -
若
Maven
未识别到该子项目,则右键为其添加Maven
支持。
-
-
然后,在
Settings
中手动配置Maven
的安装目录、配置文件和本地仓库。如下图所示:
- 重新编译项目,并重新加载
Maven
项目。如下图所示:
附2:解决单元测试包不存在的问题
由于Spring Boot2.2
之前版本使用的是Junit4
,而Spring Boot2.2
之后的版本的使用的是Junit5
。若出现spring boot org.junit.jupiter.api
包不存在的问题,则需要在pom.xml
文件中手动导入Junit5
相关的依赖包。
pom.xml
文件:
1 | <dependency> |
3.3、项目初始结构分析
通过上面步骤完成了基础项目的创建。就会自动生成以下文件:
(1)程序的主启动类(入口)及main
函数。
Springboot01HelloworldApplication.java
文件:
1 | package com.atangbiji; |
(2)一个application.properties
配置文件。
(3)一个测试类。
(4)一个pom.xml
文件。
pom.xml
文件:
1 |
|
**注:**所有的Spring Boot
的依赖的项目名称都是spring-boot-starter-XXX
,它们又被称作“启动器”。
3.4、建立项目的基本结构
在程序的主启动类(Springboot01HelloworldApplication
)的同级目录下:
- 新建一个
controller
包,用于存放控制器代码; - 新建一个
service
包,用于存放业务层代码; - 新建一个
dao
包,用于存放持久层代码(映射器接口及其对应的映射器配置文件); - 新建一个
pojo
包,用于存放实体类; - 新建一个
utils
包,用于存放我们封装的各种工具。
**注:**程序的主启动类一定要与controller
、service
、dao
、pojo
、utils
包在同级目录下,否则识别不到【约定大于配置】。
3.5、编写控制器接口
在controller
包下新建一个HelloController
类。
HelloController.java
文件:
1 | package com.atangbiji.controller; |
3.6、启动测试
- 启动主启动类中的
main
函数,如下图所示:
此时,Tomcat
启动成功。如下图所示:
- 在浏览器中输入
http://localhost:8080/hello
,页面访问成功。访问结果如下图所示:
3.7、将项目打成jar包
双击maven
的package
(打包)按钮,对项目进行打包。若打包成功,则会在target
目录下生成一个jar
包。如下图所示:
打成了jar
包后,该项目就可以在任何地方运行了!
**注:**在以前开发的web
单体应用中,所有的功能被放在一个war
包内;而使用Spring Boot
开发的微服务项目中,各个项目会被打包成一个个可执行的jar
包。
3.8、小结
简单几步,就完成了一个web
接口的开发,SpringBoot
就是这么简单。所以我们常用它来建立我们的微服务项目!
附:彩蛋——自定义banner图案
如何更改启动时显示的字符拼成的字母,也就是banner
图案呢?
只需一步:在项目下的resources
目录下新建一个banner.txt
文件即可。
**注:**图案可以到网站:https://www.bootschool.net/ascii 生成,然后拷贝到文件中即可!
4、Spring Boot运行原理初探(重点)
Spring Boot
项目到底是怎么运行的呢?Maven
项目,我们一般从pom.xml
文件探究起。
4.1、pom.xml
探究
4.1.1、父依赖
(1)Spring Boot
项目主要依赖的是一个父项目(spring-boot-starter-parent
)。
pom.xml
文件:
1 | <!-- 父项目 --> |
注:spring-boot-starter-parent
项目的主要作用是:
-
对项目的资源进行过滤。
spring-boot-starter-parent-2.7.7.pom
文件:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20<!-- 资源过滤 -->
<resources>
<resource>
<directory>${basedir}/src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/application*.yml</include>
<include>**/application*.yaml</include>
<include>**/application*.properties</include>
</includes>
</resource>
<resource>
<directory>${basedir}/src/main/resources</directory>
<excludes>
<exclude>**/application*.yml</exclude>
<exclude>**/application*.yaml</exclude>
<exclude>**/application*.properties</exclude>
</excludes>
</resource>
</resources> -
对项目的插件进行管理。
spring-boot-starter-parent-2.7.7.pom
文件: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
27
28
29
30
31
32
33
34
35
36
37
38<!-- 插件管理(部分) -->
<pluginManagement>
<plugins>
<plugin>
<groupId>org.jetbrains.kotlin</groupId>
<artifactId>kotlin-maven-plugin</artifactId>
<version>${kotlin.version}</version>
<configuration>
<jvmTarget>${java.version}</jvmTarget>
<javaParameters>true</javaParameters>
</configuration>
<executions>
<execution>
<id>compile</id>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
</execution>
<execution>
<id>test-compile</id>
<phase>test-compile</phase>
<goals>
<goal>test-compile</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<parameters>true</parameters>
</configuration>
</plugin>
……
</plugins>
</pluginManagement>
(2)点击进入该父项目(spring-boot-starter-parent
),发现它还有一个父项目(spring-boot-dependencies
)。
spring-boot-starter-parent-2.7.7.pom
文件:
1 | <!-- 父项目的父项目 --> |
spring-boot-dependencies
项目才是真正管理SpringBoot
应用中所有依赖及其版本的地方。spring-boot-dependencies
项目的主要作用是:
-
对
SpringBoot
项目中依赖的所有jar
包的版本进行管理。spring-boot-dependencies-2.7.7.pom
文件: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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70<!-- 依赖包版本管理(部分) -->
<properties>
<activemq.version>5.16.5</activemq.version>
<antlr2.version>2.7.7</antlr2.version>
<appengine-sdk.version>1.9.98</appengine-sdk.version>
<build-helper-maven-plugin.version>3.3.0</build-helper-maven-plugin.version>
<commons-pool.version>1.6</commons-pool.version>
<commons-pool2.version>2.11.1</commons-pool2.version>
<db2-jdbc.version>11.5.7.0</db2-jdbc.version>
<dependency-management-plugin.version>1.0.15.RELEASE</dependency-management-plugin.version>
<git-commit-id-plugin.version>4.9.10</git-commit-id-plugin.version>
<h2.version>2.1.214</h2.version>
<hibernate.version>5.6.14.Final</hibernate.version>
<hibernate-validator.version>6.2.5.Final</hibernate-validator.version>
<htmlunit.version>2.60.0</htmlunit.version>
<httpclient.version>4.5.14</httpclient.version>
<httpclient5.version>5.1.4</httpclient5.version>
<httpcore.version>4.4.16</httpcore.version>
<httpcore5.version>5.1.5</httpcore5.version>
<javax-activation.version>1.2.0</javax-activation.version>
<javax-annotation.version>1.3.2</javax-annotation.version>
<javax-cache.version>1.1.1</javax-cache.version>
<javax-json.version>1.1.4</javax-json.version>
<javax-jsonb.version>1.0</javax-jsonb.version>
<javax-mail.version>1.6.2</javax-mail.version>
<javax-money.version>1.1</javax-money.version>
<javax-websocket.version>1.1</javax-websocket.version>
<jaxen.version>1.2.0</jaxen.version>
<json-path.version>2.7.0</json-path.version>
<json-smart.version>2.4.8</json-smart.version>
<jsonassert.version>1.5.1</jsonassert.version>
<jstl.version>1.2</jstl.version>
<jtds.version>1.3.1</jtds.version>
<junit.version>4.13.2</junit.version>
<junit-jupiter.version>5.8.2</junit-jupiter.version>
<kafka.version>3.1.2</kafka.version>
<log4j2.version>2.17.2</log4j2.version>
<logback.version>1.2.11</logback.version>
<lombok.version>1.18.24</lombok.version>
<maven-clean-plugin.version>3.2.0</maven-clean-plugin.version>
<maven-compiler-plugin.version>3.10.1</maven-compiler-plugin.version>
<maven-dependency-plugin.version>3.3.0</maven-dependency-plugin.version>
<maven-deploy-plugin.version>2.8.2</maven-deploy-plugin.version>
<maven-help-plugin.version>3.2.0</maven-help-plugin.version>
<maven-install-plugin.version>2.5.2</maven-install-plugin.version>
<maven-invoker-plugin.version>3.2.2</maven-invoker-plugin.version>
<maven-jar-plugin.version>3.2.2</maven-jar-plugin.version>
<maven-javadoc-plugin.version>3.4.1</maven-javadoc-plugin.version>
<maven-resources-plugin.version>3.2.0</maven-resources-plugin.version>
<maven-war-plugin.version>3.3.2</maven-war-plugin.version>
<mongodb.version>4.6.1</mongodb.version>
<mysql.version>8.0.31</mysql.version>
<rabbit-amqp-client.version>5.14.2</rabbit-amqp-client.version>
<rabbit-stream-client.version>0.5.0</rabbit-stream-client.version>
<spring-framework.version>5.3.24</spring-framework.version>
<spring-kafka.version>2.8.11</spring-kafka.version>
<spring-security.version>5.7.6</spring-security.version>
<spring-session-bom.version>2021.2.0</spring-session-bom.version>
<sqlite-jdbc.version>3.36.0.3</sqlite-jdbc.version>
<thymeleaf.version>3.0.15.RELEASE</thymeleaf.version>
<thymeleaf-extras-data-attribute.version>2.0.1</thymeleaf-extras-data-attribute.version>
<thymeleaf-extras-java8time.version>3.0.4.RELEASE</thymeleaf-extras-java8time.version>
<thymeleaf-extras-springsecurity.version>3.0.5.RELEASE</thymeleaf-extras-springsecurity.version>
<thymeleaf-layout-dialect.version>3.0.0</thymeleaf-layout-dialect.version>
<tomcat.version>9.0.70</tomcat.version>
<versions-maven-plugin.version>2.10.0</versions-maven-plugin.version>
<webjars-locator-core.version>0.50</webjars-locator-core.version>
<xml-maven-plugin.version>1.0.2</xml-maven-plugin.version>
<xmlunit2.version>2.9.0</xmlunit2.version>
</properties>因此,以后我们导入依赖包时默认是不需要配置版本的;但是如果导入的包没有在依赖中管理,那么就需要我们手动配置版本了。
注:
Spring Boot
官方文档列出Spring Boot
项目中我们可以使用的所有依赖及其默认版本。
4.1.2、启动器
所谓“启动器”,即:Spring Boot
应用依赖的一个个spring-boot-starter-XXX
项目。
SpringBoot
将所有的功能场景都抽取出来,做成一个个的starter
(启动器),我们只需要在项目中引入这些starter
即可将所有相关的依赖都导入进来 , 我们要用什么功能就导入什么样的场景启动器即可 ;我们未来也可以自己自定义starter
。
如:spring-boot-starter-web启动器:帮我们导入了web
模块正常运行所依赖的组件。
pom.xml
文件:
1 | <!-- web场景启动器 --> |
注:Spring Boot
官方文档列出Spring Boot
项目中我们可以使用的所有启动器。
4.2、主启动类运行原理
4.2.1、默认的主启动类
Springboot01HelloworldApplication.java
文件:
1 | package com.atangbiji; |
但是**一个简单的启动类并不简单!**主启动类主要通过@SpringBootApplication
注解和SpringApplication
类调用run
方法启动,接下来我们来分析一下它们都干了什么。
注:Spring Boot
项目启动后,会像Java
应用启动一样,会在后台启动一个几百兆的Java
进程。如下图所示:
该进程对应的进程号(PID
)通常我们可以在Spring Boot
的启动log
中查看。如下图所示:
4.2.2、@SpringBootApplication注解
作用:@SpringBootApplication
用来标注一个主程序类,说明这是一个Spring Boot
应用。 SpringBoot
就通过运行这个类的main
方法来启动SpringBoot
应用。
点击进入SpringBootApplication
注解:可以看到上面还有很多其他注解!
SpringBootApplication.java
文件:
1 |
|
4.2.2.1、@ComponentScan注解
@ComponentScan
注解在Spring
中很重要,它对应XML
配置中的元素。
**作用:**自动扫描并加载主启动类(Springboot01HelloworldApplication
)同级目录下符合条件的组件或者bean
,将这个bean
定义加载到IOC
容器中。
4.2.2.2、@SpringBootConfiguration注解
作用:SpringBoot
的配置类,标注在某个类上,表示这是一个SpringBoot
的配置类。
4.2.2.2.1、@Configuration注解
点击进入@SpringBootConfiguration
注解:可以看到上面还有很多其他注解!
SpringBootConfiguration.java
文件:
1 |
|
这里的@Configuration
注解说明:这是一个配置类。配置类就对应Spring
的xml
配置文件。
4.2.2.2.2、@Component注解
点击进入@Configuration
注解:可以看到它也是一个组件(Component
)!
Configuration.java
文件:
1 |
|
这里的@Component
注解说明:主启动类本身也是Spring
中的一个组件(Bean
)而已,负责启动Spring Boot
应用!
接下来,我们回到SpringBootApplication
注解中继续分析。
4.2.2.3、@EnableAutoConfiguration注解(重点)
**作用:**开启自动配置功能。
以前我们需要自己手动配置的东西,而现在SpringBoot
可以自动帮我们配置 ;通过@EnableAutoConfiguration
注解让SpringBoot
开启自动配置功能后,自动配置才能生效。
4.2.2.3.1、@AutoConfigurationPackage注解
(1)点击进入@EnableAutoConfiguration
注解:可以看到它包含一个@AutoConfigurationPackage
注解。
EnableAutoConfiguration.java
文件:
1 |
|
这里的@AutoConfigurationPackage
注解的作用是:自动配置包。
(2)点击进入@AutoConfigurationPackage
注解:可以看到它通过@Import(AutoConfigurationPackages.Registrar.class)
注解向容器中导入“自动配置包注册器”组件。
AutoConfigurationPackage.java
文件:
1 |
|
注:
-
这里的
@import
注解是Spring
的底层注解,它的作用是:向容器中导入组件(Bean
)。 -
这里的
Registrar.class
的作用是:将主启动类的所在包及包下面所有子包里面的所有组件扫描到Spring IOC
容器中。
接下来,返回上一级,我们回到EnableAutoConfiguration
注解中继续分析。
4.2.2.3.2、通过@Import注解导入自动配置导入选择器
点击进入@EnableAutoConfiguration
注解:可以看到它通过@Import({AutoConfigurationImportSelector.class})
注解,向IOC
容器中导入自动配置导入选择器(AutoConfigurationImportSelector
)组件(Bean
)。
自动配置导入选择器会导入哪些组件的选择器呢?
(1)点击进入AutoConfigurationImportSelector
类,可以发现:这个类中有一个getCandidateConfigurations
方法。
AutoConfigurationImportSelector.java
文件:
1 | //获取候选的配置 |
注:
getCandidateConfigurations
方法的作用是:获取候选的配置。- 该方法通过调用
ImportCandidates
的load
方法导入候选的配置!
(2)点击进入ImportCandidates
类的load()
方法,可以发现:其中加载了本地META-INF/spring
目录下的自动配置核心文件(即org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件)。
ImportCandidates.java
文件:
1 | //自动配置核心文件的本地目录 |
(3)查看Spring Boot
自动配置的核心文件。
org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件是Spring Boot
自动配置的核心文件。它位于spring-boot-autoconfigure-2.7.7.jar
包的META-INF/spring
目录下,如下图所示:
注:
Spring Boot
自动配置的核心文件中的所有类(Beans
)都是通过java
配置类的方式显式地配置到Spring IOC
容器中的。Spring Boot
自动配置的核心文件中没有的类(Beans
)都需要我们手动进行配置。
(4)我们在自动配置的核心文件中随便找一个自动配置类进行全局搜索,如:WebMvcAutoConfiguration
。
可以发现:这些类的都是JavaConfig
配置类,而且都注入了一些Bean
。我们可以找一些自己认识的自动配置类,看着熟悉一下!
所以,自动配置真正实现是从classpath
中搜寻所有META-INF/spring/
目录下的org.springframework.boot.autoconfigure.AutoConfiguration.imports
配置文件,并将其中对应的配置项,通过反射实例化为自动配置类,然后将这些都汇总成为一个实例并加载到Spring IOC
容器中。
4.2.2.3.3、结论
(1)SpringBoot
所有的自动配置都是在主启动类启动时扫描并加载的。
(2)SpringBoot
自动配置好的这些组件(Bean
),需要我们导入对应的启动器(spring-boot-starter-XXX
)后才会生效。即:只有@ConditionalOnXXX
注解中的条件都满足时,自动配置的相应组件(Bean
)才会生效。
(3)SpringBoot
在启动的时候,从类路径(classpath
)的META-INF/spring
目录下的org.springframework.boot.autoconfigure.AutoConfiguration.imports
配置文件中获取值。
(4)SpringBoot
将这些值作为自动配置类导入Spring IOC
容器,自动配置类就生效,帮我们进行自动配置工作。
(5)整个J2EE
的整体解决方案和自动配置都在spring-boot-autoconfigure
的jar
包中。
(6)SpringBoot
会向容器中导入非常多的自动配置类(xxxAutoConfiguration
),就是向容器中导入这个场景需要的所有组件,并配置好这些组件。
(7)有了自动配置类,免去了我们手动编写配置注入功能组件等工作。
4.2.3、SpringApplication类
4.2.3.1、SpringApplication类的作用
SpringApplication
类主要完成以下四件事情:
- 推断应用的类型是普通的项目还是
Web
项目。 - 查找并加载所有可用初始化器,并设置到
initializers
(初始化)属性中。 - 找出所有的应用程序监听器,设置到
listeners
属性中。 - 推断并设
main
方法的定义类,找到运行的主类。
4.2.3.2、run方法执行流程分析
跟着源码和这幅图就可以探究run
方法执行流程了!
5、yaml配置文件
5.1、配置文件
SpringBoot
使用一个全局的配置文件,配置文件名称是固定的。
application.properties
- 语法结构:
key=value
- 只能保存
key=value
键值对。
- 语法结构:
application.yml
- 语法结构:
key:
空格value
- 既可以保存
key: value
键值对,又可以保存对象和数组。
- 语法结构:
**配置文件的作用:**修改SpringBoot
自动配置的默认值。如:我们可以在配置文件中修改Tomcat
默认启动的端口号等。
注:Spring Boot
官方提供了可配置属性的参考文档。
5.2、yaml概述
YAML
是"YAML Ain't a Markup Language"
(YAML
不是一种标记语言)的递归缩写。
**YAML
语言以数据为中心的标记语言!**它比XML
和JSON
更适合作为配置文件。
如:一个简单的端口配置。
- 传统
xml
配置:
1 | <server> |
yaml
配置:
1 | server: |
5.3、yaml基础语法
说明:yaml
语法要求严格!
1、空格不能省略。
2、以缩进来控制层级关系,只要是左边对齐的一列数据都是同一个层级的。
3、属性和值的大小写都是十分敏感的。
(1)字面量:普通的值 [ 数字、布尔值、字符串 ]
语法格式:
1 | key: value |
注:
-
字面量直接写在后面就可以,字符串默认不用加上双引号或者单引号。
-
“ ”
双引号不会转义字符串里面的特殊字符 , 特殊字符会作为本身想表示的意思。如:
name: "kuang \n shen"
输出:kuang
换行shen
-
''
单引号,会转义特殊字符 , 特殊字符最终会变成和普通字符一样输出。如:
name: ‘kuang \n shen’
输出:kuang \n shen
(2)对象、Map(键值对)
语法格式:
1 | #对象、Map格式(多行缩进写法) |
或
1 | #对象、Map格式(行内写法) |
如:
1 | #多行缩进写法 |
1 | #行内写法 |
(3)数组(List、set)
语法格式:
1 | #数组(多行缩进写法) |
或
1 | #数组(行内写法) |
如:
1 | #多行缩进写法 |
1 | #行内写法 |
5.4、通过yaml配置文件注入类属性(重点)
yaml
文件更强大的地方在于:它可以直接给我们的Java
类【如:实体类(pojo
)、配置类(xxxProperties
)等】绑定起来,并注入匹配值!
**注:**实际项目中,我们常使用该方法给配置类注入值。
接下来,我们以实体类为例,介绍如何通过yaml
配置文件来给Java
类的属性赋值。
我们首先来回顾一下,原来是如何通过注解方式实体类注入匹配值的。
5.4.1、方式一:通过注解给实体类属性赋值(回顾)
(1)在springboot
项目的pom.xml
文件中导入lombok
的依赖。
pom.xml
文件:
1 | <!-- lombok依赖 --> |
(2)在程序的主启动类的同级目录下新建一个pojo
包,用于存放实体类。在其中编写一个Dog
实体类,并使用@Value
注解给bean
注入属性值。
Dog.java
文件:
1 | package com.atangbiji.pojo; |
(3)在SpringBoot
的测试类中输出Dog
对象。
Springboot01HelloworldApplicationTests.java
文件:
1 | package com.atangbiji; |
(4)运行测试函数,@Value注入成功,结果成功输出。如下图所示:
接下来,我们再来看看yaml
文件是如何给实体类注入匹配值的。
5.4.2、方式二:通过yaml配置文件给实体类属性赋值(推荐)
(1)在springboot
项目的resources
根目录下新建一个application.yaml
文件。
application.yaml
文件:
1 | person: |
**注:**我们还可以在yaml
配置文件中使用占位符${}
。
(2)在pojo
包下新建一个Person
实体类。我们在Person
类上使用**@ConfigurationProperties
**注解加载全局的yaml
配置文件注入属性的值。
Person.java
文件:
1 | package com.atangbiji.pojo; |
其中:
@ConfigurationProperties
的作用是:将配置文件中配置的每一个属性的值,映射到当前组件中;告诉SpringBoot
将当前类中的所有属性和配置文件中相关的配置项进行绑定。- 参数
prefix = “person”
表示:将配置文件中person
下面的所有属性与当前实体类进行绑定。
注:
@configurationProperties
:默认从全局配置文件中获取值。- 我们也可以**
@PropertySource
注解和@Value
**注解加载指定的配置文件中的值(详见5.4.3节)。 - 当添加
@ConfigurationProperties
时,IDEA
会提示:Spring Boot
配置注解处理器**(Configuration Annotation Processor)**没有找到,并让我们查看官方文档。如下图所示:
- 因为官方文档结构,点击查看文档可能会报404错误。仔细查看官方文档,可以找到配置文件处理器依赖!如下图所示:
(3)在springboot
项目的pom.xml
文件中导入配置文件处理器的依赖。
pom.xml
文件:
1 | <!-- 配置文件处理器依赖 --> |
注:
- 若导入配置文件处理器依赖,则配置文件进行绑定实体类就会有提示(需要重启)。
- 若未导入配置文件处理器依赖,程序也可以运行,但IDEA会报红。
(4)在SpringBoot
的测试类中输出Person
对象。
Springboot01HelloworldApplicationTests.java
文件:
1 | package com.atangbiji; |
(5)运行测试函数,yaml
配置文件中的属性与当前实体类绑定成功,结果成功输出。如下图所示:
5.4.3、方式三:通过properties配置文件给实体类属性赋值
(1)在springboot
项目的resources
根目录下新建一个user.properties
文件。
user.properties
文件:
1 | name= 张三 |
**注:**默认情况下,properties
配置文件中的中文会乱码,我们需要将properties
配置文件的默认编码方式设置为:UTF-8
。
(2)在pojo
包下新建一个User
实体类。我们在User
类上使用**@PropertySource
注解加载指定的配置文件,并使用@Value
注解和Spring
表达式**(SpEL
)注入属性的值。
User.java
文件:
1 | package com.atangbiji.pojo; |
**注:通过properties
配置文件给实体类注入值需要在每一个属性上使用@Value
**注解为其单独赋值,比较麻烦;而通过yaml
配置文件给实体类注入值方则不需要。
(3)在SpringBoot
的测试类中输出User
对象。
Springboot01HelloworldApplicationTests.java
文件:
1 | package com.atangbiji; |
(4)运行测试函数,properties
配置文件中的属性与当前实体类绑定成功,结果成功输出。如下图所示:
5.4.4、对比与小结
@ConfigurationProperties
注解与@Value
注解功能对比如下图所示:
(1)@ConfigurationProperties
注解只需要写一次即可; @Value
注解则需要给每个字段都添加。
(2)什么是**松散绑定(又称:宽松绑定)**呢? 它是@ConfigurationProperties
注解支持的格式,也是SpringBoot
主推的做属性绑定的方式。如:我们的yml
中写的last-name
,和Java
类中的lastName
(驼峰命名)属性是一样的,-
后面跟着的字母默认是大写的。这就是松散绑定。
(3)SpEL
即:Spring
表达式。
(4)JSR303
数据校验,这个就是我们可以在字段上增加一层过滤器验证,可以保证数据的合法性。
(5)复杂类型封装:yml
中可以封装对象,使用value
就不支持。
结论:
- 通过
yml
配置文件和properties
配置文件都可以注入Java
类的属性值,强烈推荐yml
。 - 若我们在某个业务中,只需要获取配置文件中的某个值,则可以使用一下
@value
注解。 - 若我们专门编写了一个
JavaBean
来和配置文件进行一一映射,就直接使用@configurationProperties
注解,不要犹豫!
6、JSR303数据校验
6.1、使用方法
JSR-303
是JAVA EE 6
中的一项子规范,叫做Bean Validation
(校验)。
Springboot
中可以用@validated
注解开启校验数据,若数据异常则会统一抛出异常,方便异常中心统一处理。
具体使用步骤如下:
(1)在上述Springboot
项目的基础上,在pom.xml
文件中导入JSR303
数据校验(Validation
)的启动器(依赖)。
pom.xml
文件:
1 | <!-- JSR303数据校验依赖 --> |
(2)使用@validated
注解开启校验数据,并在Java
类中进行具体数据校验。如:Person
实体类。
Person.java
文件:
1 | package com.atangbiji.pojo; |
(3)修改Person
实体类绑定的yaml
配置文件。
application.yaml
文件:
1 | person: |
(4)在SpringBoot
的测试类中输出Person
对象。
Springboot01HelloworldApplicationTests.java
文件:
1 | package com.atangbiji; |
(5)运行测试函数,后台输出错误并提示:yaml
配置文件中的age
和birth
属性不满足要求。如下图所示:
6.2、校验项
点击导入的javax.validation.constraints
包,可以查看我们可以使用的所有校验项,如下图所示:
各校验项的详细信息和适用类型如下:
注解 | 详细信息 | 适用类型 |
---|---|---|
@Null |
被注解的字段必须为空 | |
@NotNull |
被注解的字段必须不为空 | |
@NotBlank |
带注解的元素不能为null ,并且必须至少包含一个非空白字符 |
|
@NotEmpty |
带注解的元素不能为null 也不能为空 |
String (长度)集合(大小)数组(长度) |
@AssertTrue |
检查该字段必须为True |
Boolean |
@AssertFalse |
检查该字段必须为False |
Boolean |
@Min(value) |
被注解的字段必须大于等于指定的最小值 | |
@Max(value) |
被注解的字段必须小于等于指定的最大值 | |
@Negative |
带注解的元素必须是严格的负数(0被认为是无效值) | BigDecimal ,BigInteger ,byte ,short ,int ,long 及其包装类 |
@NegativeOrZero |
带注解的元素必须是严格的负数或0 | BigDecimal ,BigInteger ,byte ,short ,int ,long 及其包装类 |
@Positive |
带注解的元素必须是严格的正数(0被认为是无效值) | BigDecimal ,BigInteger ,byte ,short ,int ,long 及其包装类 |
@PositiveOrZero |
带注解的元素必须是严格的正数或0 | BigDecimal ,BigInteger ,byte ,short ,int ,long 及其包装类 |
@DecimalMin |
被注解的字段必须大于等于指定的最小值 | BigDecimal ,BigInteger ,byte ,short ,int ,long 及其包装类 |
@DecimalMax |
被注解的字段必须小于等于指定的最大值 | BigDecimal ,BigInteger ,byte ,short ,int ,long 及其包装类 |
@Size(min=,max=) |
被注解的字段的size 必须在min 和max 之间,不需要判空 |
字符串、数组、集合 |
@Digits(integer, fraction) |
被注解的字段必须在指定范围内,整数部分长度小于integer ,小数部分长度小于fraction |
字符串、数组、集合 |
@Past |
被注解的字段必须是一个过去的日期时间 | |
@PastOrPresent |
被注解的字段必须是过去的或现在的日期时间 | |
@Future |
被注解的字段必须是一个将来的日期时间 | |
@FutureOrPresent |
被注解的字段必须是现在的或将来的日期时间 | |
@Email |
字符串必须是格式正确的电子邮件地址 | String |
@Pattern(value) |
被注解的字段必须符合指定的正则表达式 |
7、多配置文件
7.1、配置文件加载位置
Spring Boot
官方默认的配置文件加载位置有以下4个:
(1)file:./config/
即:项目路径(src
的同级目录)下的config
目录下。
(2)file:./
即:项目的根目录(src
的同级目录)下。
(3)classpath:/config/
即:类路径(resources
的同级目录)下的config
目录下。
(4)classpath:/
(默认)
即:类路径的根目录(resources
的同级目录)下。
注:Spring Boot
启动默认会扫描上述目录下的application.properties
或者application.yml
文件作为Spring boot
的默认配置文件。
7.2、配置文件加载顺序
Spring Boot
加载四个位置配置文件优先级为:
(1)file:./config/
>(2) file:./
> (3)classpath:/config/
> (4)classpath:/
(默认)
注:
- 高优先级的配置会覆盖低优先级的配置。
- 相同的配置文件加载目录下,如果我们同时配置了
yaml
文件和properties
文件,并且没有激活其它环境,那么默认会使用properties
文件中的配置!
8、多环境切换
项目开发过程中往往需要有开发、生产、测试等多套环境。
profile
是Spring
为我们提供的不同环境下激活不同配置的功能支持。我们可以通过激活不同的环境,快速实现环境的切换。具体实现方式如下:
8.1、方式一:配置多个配置文件(推荐)
(1)在配置文件加载目录下创建多个配置文件,并将它们命名为:application-{profile}.properties
或application-{profile}.yml
(固定写法)。如:
application-dev.properties
文件:代表开发环境配置。application-pro.properties
文件:代表生产环境配置。application-test.properties
文件:代表测试环境配置。
但是Springboot
默认并不会直接启用这些配置文件,它默认会使用application.properties
主配置文件。
(2)在主配置文件中选择当前需要激活的环境。
application.properties
文件:
1 | #通过Spring的profile激活开发环境配置 |
8.2、方式二:在同一个yaml中配置多文档块(不推荐)
使用yaml
文件去实现多环境切换,不需要创建多个配置文件。我们只需在同一个yaml
配置文件中配置多文档块即可配置多套环境。
(1)在yaml
主配置文件中配置多文档块。如:
application.yaml
文件:
1 | #文档块1 |
**注:**各环境之间使用---
进行分隔。
9、Spring Boot自动配置原理(重点)
配置文件到底能写哪些属性?怎么写?
SpringBoot
官方文档中列出了所有可以配置的属性,但我们无法全部记住。如果掌握并理解了Spring Boot
自动配置的原理,我们便可以通过查看源码的方式,知道Spring Boot
到底有哪些属性可以配置,以及如何配置!进而以不变应万变!
9.1、分析过程
9.1.1、查看自动配置核心文件
在第4.2.2.3
节中已经对主启动类上的@EnableAutoConfiguration
注解进行了分析。并发现:Spring Boot
自动装配其实是加载了本地spring-boot-autoconfigure-2.7.7.jar
包的META-INF/spring
目录下的自动配置核心文件(即org.springframework.boot.autoconfigure.AutoConfiguration.imports
文件)。
接下来,我们以**HttpEncodingAutoConfiguration
(Http
编码自动配置类)**为例解释自动配置原理。
9.1.2、全局搜索自动配置类
全局搜索HttpEncodingAutoConfiguration
自动配置类。
HttpEncodingAutoConfiguration.java
文件:
1 | //表示这是一个自动配置类,和以前Spring中编写的xml配置文件一样,也可以向IOC容器中添加组件。 |
可以发现:这些类的都是JavaConfig
自动配置类,而且都注入了一些Bean
。其中:
(1)@AutoConfiguration
注解:表示这是一个自动配置类,和以前Spring
中编写的xml
配置文件一样,也可以向IOC
容器中添加组件。
(2)@EnableConfigurationProperties(ServerProperties.class)
注解:表示启动指定类的属性配置功能。
点击进入ServerProperties
类,可以发现:
xxxProperties
类就是一个属性配置类,并通过配置文件的方式给该类中的属性配置值(详见第5.4.2
节)。
ServerProperties.java
文件:
1 | //通过配置文件配置属性值(参数prefix = “server”表示:将配置文件中server下面的所有属性与当前实体类进行绑定。) |
properties
或yaml
配置文件中可以配置的属性与上述属性配置类中的属性完全一致!如下图所示:
(3)@ConditionalOnXXX
注解:表示自动配置类生效的条件。它们的底层都包含@Conditional
注解。其中:
-
@ConditionalOnWebApplication(type = ConditionalOnWebApplicatiweb
应用,如果是,则当前配置类生效。 -
@ConditionalOnClass(CharacterEncodingFilter.class)
注解表示:判断当前项目有没有SpringMVC
中进行乱码解决的过滤器。 -
@ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)
注解表示:判断配置文件中是否存在某个配置(spring.servlet.encoding.enabled
)。即使配置文件中不配置spring.servlet.encoding.enabled=true
,也是默认生效的。
注:SpringBoot
自动配置好的这些组件(Bean
),需要我们导入对应的启动器(spring-boot-starter-XXX
)后才会生效。即:只有@ConditionalOnXXX
注解中的条件都满足时,自动配置的相应组件(Bean
)才会生效。
(4)自动配置类的作用就是:向容器中添加组件,且这些组件的某些值需要从属性配置类中获取。即:从(properties
或yaml
)配置文件中获取指定的值和Bean
的属性进行绑定。
这就是Spring Boot自动装配的原理!
9.1.3、@Conditional注解
9.1.3.1、含义
@Conditional
注解表示:自动配置类必须在一定的条件下才能生效。
9.1.3.2、派生注解
@Conditional
派生注解及其作用,如下图所示:
9.1.3.3、输出自动配置报告
Spring Boot那么多默认的自动配置类,每一个都必须在一定的条件下才能生效。也就是说,我们加载了这么多的自动配置类,但并不是所有的都生效了。
我们怎么知道哪些自动配置类生效了呢?
我们可以在配置文件中启用debug=true
属性,在控制台输出自动配置报告,这样我们就可以很方便的知道哪些自动配置类生效了。
application.properties
文件:
1 | #开启springboot的调试类 |
运行主启动类,输出结果如下:
注:
-
Positive matches
:(自动配置类启用,即:正匹配) -
Negative matches
:(自动配置类未启用,没有匹配成功,即:负匹配) -
Unconditional classes
:(没有条件的自动配置类)
9.2、结论
properties
或yaml
配置文件中可以配置的属性就是所有自动配置类(xxxAutoConfiguration
)对应的**属性配置类(xxxProperties
)**中的属性!- 自动配置真正实现是从
classpath
中搜寻所有META-INF/spring/
目录下的org.springframework.boot.autoconfigure.AutoConfiguration.imports
配置文件,并将其中对应的配置项,通过反射实例化为自动配置类,然后将这些都汇总成为一个实例并加载到Spring IOC
容器中。 - 只有**
@ConditionalOnXXX
注解**中的条件都满足时,自动配置类及其配置的相应组件(Bean
)才会生效。 - 如果某个自动配置类生效,那么该配置类就会向容器中添加各种组件。
- 这些组件的属性是从对应的属性配置类(
xxxProperties
)中获取的,这些属性配置类中的每一个属性又是和(properties
或yaml
)配置文件绑定的。 - 所有在配置文件中能配置的属性都封装在属性配置类(
xxxxProperties
)类中。 - 配置文件能配置什么就可以参照某个功能对应的这个属性类(先找到对应的自动配置类,再找到对应的属性配置类)。
9.3、精髓(重点)
Spring Boot
自动配置原理的精髓如下图所示:
(1)SpringBoot
在启动时会加载大量的自动配置类。
(2)我们需要查看SpringBoot
默认写好的自动配置类当中是否存在我们需要的功能。(若不存在,则需要我们手动配置)
(3)若存在,则我们再来看这个自动配置类中到底配置了哪些组件(只要我们要用的组件存在在其中,我们就不需要再手动配置了)。
(4)自动配置类向容器中添加组件的时候,会从属性配置类中获取某些属性。我们只需要在配置文件中指定这些属性的值即可!
注:Spring Boot
自动配置的两个核心类:
-
xxxAutoConfigurartion
:自动配置类- 作用:向容器中添加组件。
- 自动配置类添加的这些组件的某些值需要从属性配置类中获取。即:从(
properties
或yaml
)配置文件中获取指定的值和Bean
的属性进行绑定。
-
xxxxProperties
:属性配置类- 作用:配置自动配置类添加的这些组件的某些参数的值。即:封装(
properties
或yaml
)配置文件的内容,供自动配置类使用。 - 通过(
properties
或yaml
)配置文件的方式给属性配置类中的属性配置值。
- 作用:配置自动配置类添加的这些组件的某些参数的值。即:封装(
10、自定义启动器
我们分析完源码并理解自动装配的原理后,我们可以尝试自定义一个启动器来玩玩!
10.1、命名归约
(1)官方命名
- 前缀:
spring-boot-starter-xxx
- 比如:
spring-boot-starter-web....
(2)自定义命名:
- 后缀:
xxx-spring-boot-starter
- 比如:
mybatis-spring-boot-starter
10.2、编写启动器
(1)在IDEA
中新建一个项目名称为:spring-boot-starter-diy
的空项目,将其作为父项目。
(2)点击项目结构按钮,在父项目中新建一个模块(Module
),并在其中创建一个普通的Maven子项目,项目名称为atang-spring-boot-starter
。
**注:**启动器模块是一个空jar
模块,仅提供辅助性依赖管理,这些依赖可能用于自动装配或者其他类库。
(3)再在父项目中新建一个模块(Module
),并在其中创建一个项目名称为atang-spring-boot-starter-autoconfigure
的Spring Initializr
项目。
- 选择
SpringBoot 2.7.7
后,不选择任何初始化的组件,直接下一步至Finish
即可。
- 此时,项目结构如下图所示:
(4)在我们自定义的启动器中导入autoconfigure
的依赖!
pom.xml
文件:
1 | <!-- 自定义启动器依赖 --> |
(5)修改自定义的自动配置模块。
- 先删除
autoconfigure
项目下IDEA
自动生成的.mvn
文件夹、.gitignore
、HELP.md
、mvnw
、mvnw.cmd
文件。 - 再删除
Spring Boot
项目默认生成的AtangSpringBootStarterAutoconfigureApplication.java
文件、application.properties
文件以及test
文件夹。 pom.xml
文件中只留下一个spring-boot-starter
,这是所有的启动器基本配置!
此时,项目结构如下图所示:
pom.xml
文件:
1 |
|
注:
- 记得选择
Spring Boot 2.7.7
版本,否则IDEA
默认创建Spring Boot 3.0.1
项目,生成的父项目(spring-boot-starter-parent
)的版本号和Java
版本号可能存在问题,记得修正。 - 若
Maven
未识别到该子项目,则右键为其添加Maven
支持。
(6)先将java
和resources
文件夹分别标记为源文件和资源文件的根目录。然后在com.atangbiji
包下新建一个HelloService
类,用于编写自己的服务。
HelloService.java
文件:
1 | package com.atangbiji; |
(7)在com.atangbiji
包下新建一个HelloProperties
属性配置类。
HelloProperties.java
文件:
1 | package com.atangbiji; |
注:当添加@ConfigurationProperties
时,IDEA
会提示:Spring Boot
配置注解处理器(Configuration Annotation Processor)没有找到,并让我们查看官方文档。(参见第5.4.2
节)此时,需要在Spring Boot
项目的pom.xml
文件中导入配置文件处理器的依赖。
pom.xml
文件:
1 | <!-- 配置文件处理器依赖 --> |
(8)在com.atangbiji
包下新建一个HelloServiceAutoConfiguration
自动配置类,并注入Bean
。
HelloServiceAutoConfiguration.java
文件:
1 | package com.atangbiji; |
(9)在resources
目录下新建一个META-INF\spring
目录,并在该目录下编写一个自己的org.springframework.boot.autoconfigure.AutoConfiguration.import
文件。
org.springframework.boot.autoconfigure.AutoConfiguration.import
文件:
1 | com.atangbiji.HelloServiceAutoConfiguration |
**注:**该文件为Text
文本格式。
(10)编写完成后,把自己编写的jar
包安装到maven
仓库中!
注:
-
Maven
可以通过install
命令将自己编写的jar
文件安装到自己的本地仓库中 。 -
安装成功后,
target
目录下生成相应的jar
包。如下图所示:
10.3、测试
(1)在父项目中新建一个模块(Module
),并在其中创建一个项目名称为atang-start-test
的Spring Initializr
(版本:2.7.7
)Web
项目,用于测试我们自己编写的启动器。
注:SpringBoot
选择2.7.7
版本,并选择Spring Web
作为初始化组件。
(2)先删除IDEA
自动生成的.mvn
文件夹、.gitignore
、HELP.md
、mvnw
、mvnw.cmd
文件。
(3)在该子项目的pom.xml
文件中导入我们自己编写的启动器。
pom.xml
文件:
1 | <!--自定义启动器--> |
(4)在程序的主启动类(AtangStartTestApplication
)的同级目录下新建一个controller
包,用于存放控制器代码。并在其中编写一个HelloController
类,用于测试我们自己编写的接口。
HelloController.java
文件:
1 | package com.atangbiji.controller; |
**注:**若Maven
未识别到该子项目,则右键为其添加Maven
支持。
(5)编写application.properties
配置文件。
application.properties
文件:
1 | atang.hello.prefix="aaa" |
(6)启动主启动类中的main
函数,在浏览器中输入http://localhost:8080/hello
,页面访问成功。访问结果如下图所示:
温馨提示:学完的东西一定要多下去实践!
(持续更新中…… )
关注**“阿汤笔迹”** 微信公众号,获取更多学习笔记。
原文地址:http://www.atangbiji.com/2023/01/15/SpringBootInDetail01Core
博主最新文章在个人博客 http://www.atangbiji.com/ 发布。