【springboot系列】01-初识SpringBoot
【springboot系列】01-初识SpringBoot
小码同学SpringBoot介绍
来源
Spring Boot是由Pivotal团队提供的一套开源框架,可以简化spring应用的创建及部署。它提供了丰富的Spring模块化支持,可以帮助开发者更轻松快捷地构建出企业级应用。Spring Boot通过自动配置功能,降低了复杂性,同时支持基于JVM的多种开源框架,可以缩短开发时间,使开发更加简单和高效。
介绍
Spring Boot帮助你创建可以运行的独立的、基于Spring的生产级应用程序。 我们对Spring平台和第三方库采取了有主见的观点,这样你就能以最少的麻烦开始工作。 大多数Spring Boot应用程序只需要很少的Spring配置。
你可以使用Spring Boot来创建Java应用程序,可以通过使用 java -jar
或更传统的war部署来启动。
我们的主要目标是。
- 为所有的Spring开发提供一个根本性的更快、更广泛的入门体验。
- 开箱即用,但随着需求开始偏离默认值,请迅速摆脱困境。
- 提供一系列大类项目常见的非功能特性(如嵌入式服务器、安全、度量、健康检查和外部化配置)。
- 绝对没有代码生成(当不以原生镜像为目标时),也不要求XML配置。
要求
- SpringBoot 3.0 之后的版本要求JDK版本最低
JDK17
- Spring Boot 3.1.0-SNAPSHOT版本可以兼容到JDK19,包括JDK19
SpringBoot 2.x版本可以使用JDK8、JDK11等。
优点
我们使用Spring都知道,XML的配置非常多,动不动就是一堆XML配置,在SpringBoot中,它省去了这些XMl配置,省去大部分一些默认的配置,它直接帮我们配置好,我们只需要专注写我们的核心代码即可。
SpringBoot整合了非常多的第三方模块,我们只需要添加核心的配置即可,即约定大于配置的核心思想。
第一个SpringBoot项目
创建项目
创建SpringBoot项目有两个方式:
- 在IDEA本地创建(常用)
- 在官网创建项目
- 新建项目或者模块
- 选择自己需要的依赖,我这里准备构建web项目,就选择了Spring Web依赖
打开Spring官网:https://start.spring.io/
选择项目的基础信息,左边是项目环境,右边是项目的依赖,根据自己的需求选择合适的依赖。
设置好环境后,点击正下方的GENEATE
生成项目压缩包,然后解压在idea导入即可,首次导入需要下载依赖,可能要几分钟。
打开如果Java文件没有被识别到,可能是项目没有设置为maven项目,选中pom.xml文件,右键添加为maven项目即可。
创建控制器
新建一个controller
包,这个包必须要和Springboot01StartApplication
同级,然后在类里面新建一个方法,同时添加一个映射mapping
1 | package site.hikki.controller; |
启动项目
点击右上角的启动配置,修改jdk版本,我这里使用的是JDK11
,选择启动的类,默认主类就是Springboot01StartApplication
。
浏览器访问
浏览器打开http://localhost:8080/hello可以如下:
![07-Mozilla Firefox20230411-289](G:/FILE/FileSave/图片素材/博客/计算机科学/编程语言/java/【SpringBoot系列】/01-初识SpringBoot/07-Mozilla Firefox20230411-289.png)
分析SpringBoot
简介
上面我们创建了一个简单的SpringBoot项目,你会发现,我们似乎没做什么,就创建项目,然后添加一个控制器,添加一方法和控制器的注解就可以了。
对比之前我们使用Spring的时候,如果使用xml配置,创建项目,配置bean.xml配置,添加bean扫描,设置添加控制器等一系列的步骤,非常麻烦,即使使用Spring注解开发,步骤也是麻烦了许多。
我们使用了SpringBoot你会觉得,这tm才是框架啊,减少开发配置,我们只需要做我们需要的东西即可。
比如我们需要创建一个简单的Web页面,需要打开页面给我返回一个"hello world"。那这件事情的核心就是编写Web页面返回"hello world"这件事情就好了,其他事情不应该是我们操心的,这些事情应该交给框架来处理,而SpringBoot刚好帮我们处理这些事情,极大的简化开发步骤。
SpringBoot说的这么牛,下面我们看看和SpringMVC有什么不同。
Springboot01StartApplication程序
1 | package site.hikki; |
我们在启动项目时,这个类就是入口。SpringBoot的出现是为了加速Spring的开发的,而Spring程序的运行会产生一个Spring容器对象(Ioc容器)并将全部的对象(bean)交给Spring容器管理。
SpringBoot加速了Spring的开发,这个Ioc容器还在不在?经过检查,这个Ioc容器还在的,下面来测试一下:
1 |
|
可以看到,SpringBoot程序启动后,还是会创建Ioc
容器的,而上面这个Springboot01StartApplication
类就是所有程序的入口,我们称之为引导类
。
总结
- SpringBoot工程提供引导类用来启动程序
- SpringBoot工程启动后创建并初始化Spring容器
parent
1 | <parent> |
相比Spring的项目,SpringBoot的项目多了上面的几个依赖,第一个标签是继承一个坐标,继承坐标ID为org.springframework.boot
的一个依赖。
- 我们可以打开继承的这个依赖看看
1 | <parent> |
打开后可以看到,这个坐标又继承了另一个坐标,继续打开
1 | <properties> |
- 可以看到,这个坐标定义了一些属性,大概是一些依赖的版本号信息属性。
下面还有一组数据
1 | <dependencyManagement> |
这组数据大概就是定义了部分依赖,然后版本号引用了上面的版本号属性,达到统一管理版本号。
总结
- 开发SpringBoot程序要继承spring-boot-starter-parent
- spring-boot-starter-parent中定义了若干个依赖管理
- 继承parent模块可以避免多个依赖使用相同技术时出现依赖版本冲突
- 继承parent的形式也可以采用引入依赖的形式实现效果
starter
1 | <dependencies> |
我们在使用Spring项目开发时,如果我们需要使用到SpringMVC技术,那必然要使用到spring-webmvc和spring-web依赖,每次都要添加两个依赖,繁琐,并且没有什么技术含量。
SpringBoot了解到这种需求,就给这些依赖整合在一起了,不需要开发者多次添加各种依赖,秩序与添加一个依赖即可,这个依赖代表这一堆依赖,SpringBoot将这样的固定技术搭配叫做starter
。
starter定义了使用某种技术时对于依赖的固定搭配格式,也是一种最佳解决方案,使用starter可以帮助开发者减少依赖配置
spring-boot-starter-web
我们在入门案例中使用了spring-boot-starter-web
依赖,我们打开这个依赖可以看到如下这些依赖,其中包括了spring-web、spring-webmvc和带有spring-boot-starter
开头的依赖,说明这些也是一个整合的依赖,我们继续进入看看。
1 | <dependencies> |
spring-boot-starter-json
1 | <dependencies> |
我们在Web开发中,Json使用的频率是最高的,用于前后端的数据传送,而SpringBoot也把json需要的依赖也整合了,方便开发者直接使用,细看就会发现,很多依赖是我们没用过的,SpringBoot都帮我们添加进去了,SpringBoot不管你用不用得到,都给你塞进去至于你想不想要,那就你来决定,如果不想要,就使用maven的排除依赖剔除掉一部分就好,不剔除也没事,不影响项目运行。
parent和starter区别
starter是一个坐标中定了若干个坐标,以前写多个,现在写一个,是用来减少依赖配置的书写量的
parent是定义了几百个依赖版本号,以前写依赖需要自己手动控制版本,现在由SpringBoot统一管理版本,可以减少版本冲突的几率,可以说parent是用来减少依赖冲突的
实际应用
我们在开发SpringBoot时,如果需要用到某个技术,我们先去找到这个技术对应的starter
- 如果有对应的starter,直接写starter,而且无需指定版本,版本由parent提供
- 如果没有对应的starter,手写坐标即可
实际开发中如果发现坐标出现了冲突现象,确认你要使用的可行的版本号,使用手工书写的方式添加对应依赖,覆盖SpringBoot提供给我们的配置管理
- 方式一:直接写坐标
- 方式二:覆盖
中定义的版本号,就是下面这堆东西了,哪个冲突了覆盖哪个就OK了
1 | <properties> |
starter命名规则
SpringBoot官方给出了好多个starter的定义,方便我们使用,而且名称都是如下格式
1 | 命名规则:spring-boot-starter-技术名称 |
总结
- 开发SpringBoot程序需要导入坐标时通常导入对应的starter
- 每个不同的starter根据功能不同,通常包含多个依赖坐标
- 使用starter可以实现快速配置的效果,达到简化配置的目的
内嵌tomcat
我们在spring-boot-starter-web
可以看到tomcat的依赖,如下:
1 | <dependency> |
我们之前在SpringMVC时,运行的时候我们需要自带tomcat或者我们手动在maven添加一个tomcat的插件来运行,这样其实有点点麻烦,每次新建项目时都要自己手动添加tomcat插件。
然而SpringBoot又帮我们做了这件事情了,新建SpringBoot项目,不需要自己动手添加tomcat也可以运行一个JavaWeb项目,多方便啊。
我们继续进入spring-boot-starter-tomcat
依赖看看。
1 | <dependencies> |
这里面有一个核心的坐标,tomcat-embed-core
,叫做tomcat内嵌核心。就是这个东西把tomcat功能引入到了我们的程序中。目前解决了第一个问题,找到根儿了,谁把tomcat引入到程序中的?
spring-boot-starter-web
中的spring-boot-starter-tomcat
做的。之所以你感觉很奇妙的原因就是,这个东西是默认加入到程序中了,所以感觉很神奇,居然什么都不做,就有了web服务器对应的功能,再来说第二个问题,这个服务器是怎么运行的。
运行原理
Tomcat服务器是一款软件,而且是一款使用java语言开发的软件,熟悉的小伙伴可能有印象,tomcat安装目录中保存有jar包,好多个jar包
既然Tomcat是使用Java语言开发的,在Java世界中,万物皆对象,那也可以将Tomcat当做一个对象处理,那将Tomcat这个对象交给Spring容器来管理也是可以的吧,那就行了,那运行是什么东西呢?上面我们提到的tomcat核心core,就是这个下面东西
1 | <dependency> |
既然是一个对象,那使用Spring容器将tomcat对象去除,是不是就没有web服务器的功能呢?事实上是可以的,我们可以使用maven来做依赖排除就可以去到web服务器的功能。
这么说,可以去除web服务器功能,那肯定也可以添加web服务器功能。
去除tomcat web服务器
1 | <dependency> |
当我们除去tomcat web服务器
时,我们启动项目时,项目就不会一直运行着等待用户发情请求了,而是一启动马上就结束运行了。
更换web服务器
根据SpringBoot的工作机制,用什么技术,加入什么依赖就行了。SpringBoot提供了3款内置的服务器。
-
tomcat(默认):apache出品,粉丝多,应用面广,负载了若干较重的组件
-
jetty:更轻量级,负载性能远不及tomcat
-
undertow:负载性能勉强跑赢tomcat
想用哪个,加个坐标就OK。前提是把tomcat排除掉,因为tomcat是默认加载的。
1 | <dependencies> |
现在就已经成功替换了web服务器,核心思想就是用什么加入对应坐标就可以了。如果有starter,优先使用starter。
总结
- 内嵌Tomcat服务器是SpringBoot辅助功能之一
- 内嵌Tomcat工作原理是将Tomcat服务器作为对象运行,并将该对象交给Spring容器管理
- 变更内嵌服务器思想是去除现有服务器,添加全新的服务器
基础配置
在resource文件夹下有application.properties
文件,这是SpringBoot的初始配置文件,我们对项目的大多数配置都在这里配置,比如修改访问端口、数据库的连接信息、mybatis的配置等待各种配置都在这里配置。
SpringBoot的配置支持三种类型文件,.properties
、yml
、.yaml
,创建SpringBoot项目时,默认是.properties
类型文件。
编写配置
默认配置文件是.properties
类型,properties格式的文件书写规范是key=value
,如:
1 | server.port=8081 |
在日常开发中,我们不需要完全记住每一个配置的名字叫什么,大概知道包名的路径以及配置名称就可以了,idea有智能提示,减少书写步骤,比如输入个port,它就预测我需要修改端口了,直接回车输入value就好了。
配置其他
关闭运行日志图表(banner)
1 | spring.main.banner-mode=off |
设置运行日志的显示级别
1 | logging.level.root=debug |
SpringBoot启动图
我们常常可以看到有些大佬在开发时,在启动界面有这么一个图案,我们也可以整一个。
这个叫banner,需要开启运行日志图表,默认是开启的,我们将某个图案复制到resource目录下,如下图:
然后在SpringBoot配置文件配置指定启动运行日志图表,也就是启动图,这样启动SpringBoot就可以看到你的佛祖了。
1 | spring.banner.location=banner.txt |
更多Banner图案:https://www.bootschool.net/ascii
配置文件优先级
上面我们说到,SpringBoot的配置文件可以有三种格式,.properties
、yml
、.yaml
,并且这三种配置文件可以同时存在,我们可以试一下都创创建这个三种格式配置文件,测试一下优先级
文件类型书写格式
application.properties(properties格式)
1 | server.port=80 |
application.yml(yml格式)
1 | server: |
application.yaml(yaml格式)
1 | server: |
总结
优先级如下:
-
application.properties > application.yml > application.yaml
-
不同配置文件中相同配置按照加载优先级相互覆盖,不同配置文件中不同配置全部保留
yaml和yml
yaml文件
YAML(YAML Ain’t Markup Language),一种数据序列化格式。具有容易阅读、容易与脚本语言交互、以数据为核心,重数据轻格式的特点。常见的文件扩展名有两种:
- .yml格式(主流)
- .yaml格式
对于文件自身在书写时,具有严格的语法格式要求,具体如下:
大小写敏感
- 属性层级关系使用多行描述,每行结尾使用冒号结束
- 使用缩进表示层级关系,同层级左侧对齐,
只允许使用空格
(不允许使用Tab键) - 属性值前面添加空格(属性名与属性值之间使用冒号+空格作为分隔)
#号
表示注释
上述规则不要死记硬背,按照书写习惯慢慢适应,并且在Idea下由于具有提示功能,慢慢适应着写格式就行了。核心的一条规则要记住,数据前面要加空格与冒号隔开
1 | boolean: TRUE #TRUE,true,True,FALSE,false,False均可 |
此外,yaml格式中也可以表示数组,在属性名书写位置的下方使用减号作为数据开始符号,每行书写一个数据,减号与数据间空格分隔(Hexo的头文件配置就是这个格式)。
1 | subject: |
总结
- yaml语法规则
- 大小写敏感
- 属性层级关系使用多行描述,每行结尾使用冒号结束
- 使用缩进表示层级关系,同层级左侧对齐,
只允许使用空格
(不允许使用Tab键) - 属性值前面添加空格(属性名与属性值之间使用冒号+空格作为分隔)
- #号 表示注释
- 注意属性名冒号后面与数据之间有一个空格
- 字面值、对象数据格式、数组数据格式
yaml数据读取
对于yaml文件中的数据,其实你就可以想象成这就是一个小型的数据库,里面保存有若干数据,每个数据都有一个独立的名字,如果你想读取里面的数据,肯定是支持的,下面就介绍3种读取数据的方式
读取单一数据
yaml中保存的单个数据,可以使用Spring中的注解直接读取,使用@Value可以读取单个数据,属性名引用方式:${一级属性名.二级属性名……}
记得使用@Value注解时,要将该注入写在某一个指定的Spring管控的bean的属性名上方。现在就可以读取到对应的单一数据行了
总结
- 使用@Value配合SpEL读取单个数据
- 如果数据存在多层级,依次书写层级名称即可
读取全部数据
读取单一数据可以解决读取数据的问题,但是如果定义的数据量过大,这么一个一个书写肯定会累死人的,SpringBoot提供了一个对象,能够把所有的数据都封装到这一个对象中,这个对象叫做Environment
,使用自动装配注解可以将所有的yaml数据封装到这个对象中
数据封装到了Environment对象中,获取属性时,通过Environment的接口操作进行,具体方法时getProperties(String),参数填写属性名即可
总结
- 使用Environment对象封装全部配置信息
- 使用@Autowired自动装配数据到Environment对象中
读取对象数据
单一数据读取书写比较繁琐,全数据封装又封装的太厉害了,每次拿数据还要一个一个的getProperties()
,总之用起来都不是很舒服。由于Java是一个面向对象的语言,很多情况下,我们会将一组数据封装成一个对象。SpringBoot也提供了可以将一组yaml对象数据封装一个Java对象的操作
首先定义一个对象,并将该对象纳入Spring管控的范围,也就是定义成一个bean,然后使用注解@ConfigurationProperties
指定该对象加载哪一组yaml中配置的信息。
这个@ConfigurationProperties
必须告诉他加载的数据前缀是什么,这样当前前缀下的所有属性就封装到这个对象中。记得数据属性名要与对象的变量名一一对应啊,不然没法封装。其实以后如果你要定义一组数据自己使用,就可以先写一个对象,然后定义好属性,下面到配置中根据这个格式书写即可。
总结
- 使用@ConfigurationProperties注解绑定配置信息到封装类中
- 封装类需要定义为Spring管理的bean,否则无法进行属性注入
yaml文件中的数据引用
如果你在书写yaml数据时,经常出现如下现象,比如很多个文件都具有相同的目录前缀
1 | center: |
或者
1 | center: |
这个时候你可以使用引用格式来定义数据,其实就是搞了个变量名,然后引用变量了,格式如下:
1 | baseDir: /usr/local/fire |
还有一个注意事项,在书写字符串时,如果需要使用转义字符,需要将数据字符串使用双引号包裹起来
1 | lesson: "Spring\tboot\nlesson" |
总结
- 在配置文件中可以使用${属性名}方式引用属性值
- 如果属性中出现特殊字符,可以使用双引号包裹起来作为字符解析
本文章来源于我的博客:https://blog.hikki.site