1、SpringBoot 简介

1.1 什么是 SpringBoot

随着 Spring 不断的发展,涉及的领域越来越多,项目整合开发需要配合各种各样的文件,慢慢变得不那么易用简单,违背了最初的理念,甚至人称配置地狱。Spring Boot 正是在这样的一个背景下被抽象出来的开发框架,目的为了让大家更容易的使用 Spring 、更容易的集成各种常用的中间件、开源软件;

Spring Boot 基于 Spring 开发,Spirng Boot 本身并不提供 Spring 框架的核心特性以及扩展功能,只是用于快速、敏捷地开发新一代基于 Spring 框架的应用程序。也就是说,它并不是用来替代 Spring 的解决方案,而是和 Spring 框架紧密结合用于提升 Spring 开发者体验的工具。Spring Boot 以约定大于配置的核心思想,默认帮我们进行了很多设置,多数 Spring Boot 应用只需要很少的 Spring 配置。同时它集成了大量常用的第三方库配置(例如 Redis、MongoDB、Jpa、RabbitMQ、Quartz 等等),Spring Boot 应用中这些第三方库几乎可以零配置的开箱即用。

简单来说就是SpringBoot其实不是什么新的框架,它默认配置了很多框架的使用方式,就像maven整合了所有的jar包,spring boot整合了所有的框架 。

Spring Boot的主要优点:

  • 为所有Spring开发者更快的入门
  • 开箱即用,提供各种默认配置来简化项目配置
  • 内嵌式容器简化Web项目
  • 没有冗余代码生成和XML配置的要求

1.2 单体应用架构

所谓单体应用架构(all in one)是指,我们将一个应用的中的所有应用服务都封装在一个应用中。

无论是ERP、CRM或是其他什么系统,你都把数据库访问,Web访问,等等各个功能放到一个war包内。

这样做的好处是,易于开发和测试;也十分方便部署;当需要扩展时,只需要将war复制多份,然后放到多个服务器上,再做个负载均衡就可以。

单体应用架构的缺点是,哪怕我要修改一个非常小的地方,我都需要停掉整个服务,重新打包、部署这个应用war包。特别是对于一个大型应用,我们不可能把所有内容都放在一个应用里面,我们如何维护、如何分工合作都是问题。

1.3 微服务架构

微服务是什么? - 阮一峰的网络日志

all in one 的架构方式,我们把所有的功能单元放在一个应用里面。然后我们把整个应用部署到服务器上。如果负载能力不行,我们将整个应用进行水平复制,进行扩展,然后在负载均衡。

所谓微服务架构,就是打破之前 all in one 的架构方式,把每个功能元素独立出来。把独立出来的功能元素的动态组合,需要的功能元素才去拿来组合,需要多一些时可以整合多个功能元素。所以微服务架构是对功能元素进行复制,而没有对整个应用进行复制。

这样做的好处是:

  1. 节省了调用资源。
  2. 每个功能元素的服务都是一个可替换的、可独立升级的软件代码。

1.4 Hello,World - 第一个 SpringBoot 程序

官网提供的创建网站:https://start.spring.io/

下载解压之后:

正常情况下,idea 创建新项目即可

创建一个接口测试:

maven 打包:

注意:配置文件中的 <skip>true</skip> ,是让 spring-boot-maven-plugin 跳过执行 的,所以 Maven 打包时不会生成可运行 JAR,自然就没有Main-Class,运行时就报 “没有主清单属性”。

修改之后可以正常运行:

java -jar helloworld-0.0.1-SNAPSHOT.jar

2、原理

2.1 自动配置

2.1.1 pom.xml

父依赖

点进去,发现还有一个父依赖

这里才是真正管理SpringBoot应用里面所有依赖版本的地方,SpringBoot的版本控制中心;

以后我们导入依赖默认是不需要写版本;但是如果导入的包没有在依赖中管理着就需要手动配置版本了;

启动器 spring-boot-starter

springboot-boot-starter-xxx:就是spring-boot的场景启动器

spring-boot-starter-web:帮我们导入了web模块正常运行所依赖的组件;

SpringBoot将所有的功能场景都抽取出来,做成一个个的starter (启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会导入进来 , 我们要用什么功能就导入什么样的场景启动器即可 ;我们未来也可以自己自定义 starter;

2.1.1 主启动类

默认的主启动类

分析注解:

@SpringBootApplication

作用:标注在某个类上说明这个类是SpringBoot的主配置类 , SpringBoot就应该运行这个类的main方法来启动SpringBoot应用;

跟进 @Import({AutoConfigurationImportSelector.class})

查看后发现都是自动配置文件,这就是自动配置的根源

小结:

SpringBoot在启动的时候从类路径下的 META-INF/spring.factories(spring-boot-autoconfigure-2.6.13.jar!\META-INF\spring.factories)中获取 EnableAutoConfiguration 指定的自动配置值

SpringApplication

这个类主要做了以下四件事情:

1、推断应用的类型是普通的项目还是Web项目

2、查找并加载所有可用初始化器 , 设置到initializers属性中

3、找出所有的应用程序监听器,设置到listeners属性中

4、推断并设置main方法的定义类,找到运行的主类

3、SpringBoot 配置

SpringBoot使用一个全局的配置文件 , 配置文件名称是固定的

  • application.properties
    • 语法结构 :key=value
  • application.yml
    • 语法结构 :key:空格 value

**配置文件的作用 :**修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了;

yaml概述

YAML 语言教程 - 阮一峰的网络日志

yaml 语法

yaml注入配置文件

**@ConfigurationProperties **作用:将配置文件中配置的每一个属性的值,映射到这个组件中;告诉 SpringBoot 将本类中的所有属性和配置文件中相关的配置进行绑定参数 prefix = “person” : 将配置文件中的person下面的所有属性一一对应

Person{name=‘qwe’, age=1, happy=false, birth=Thu Sep 08 00:00:00 CST 1009, maps={k1=v1, k2=v2}, lists=[code, music], dog=Dog{name=‘wang’, age=1}}

加载指定的配置文件

**@PropertySource :**加载指定的配置文件;

@configurationProperties:默认从全局配置文件中获取值;


配置文件占位符

小结:

JSR303数据校验 , 可以在字段是增加一层过滤器验证 , 可以保证数据的合法性

松散绑定:yml 中写的 last-name 和 lastName是一样的

复杂类型封装,yml中可以封装对象 , 使用value就不支持

JSR303数据校验

字段是增加一层过滤器验证 , 可以保证数据的合法性

常见参数:

多环境切换

profile是Spring对不同环境提供不同配置功能的支持,可以通过激活不同的环境版本,实现快速切换环境;

多配置文件

我们在主配置文件编写的时候,文件名可以是 application-{profile}.properties/yml , 用来指定多个环境版本;

例如:

application-test.properties 代表测试环境配置

application-dev.properties 代表开发环境配置

但是Springboot并不会直接启动这些配置文件,它默认使用application.properties主配置文件;

yaml的多文档块

和properties配置文件中一样,但是使用yml去实现不需要创建多个配置文件

注意:如果yml和properties同时都配置了端口,并且没有激活其他环境 , 默认会使用properties配置文件的!

配置文件加载位置

外部加载配置文件的方式十分多,我们选择最常用的即可,在开发的资源文件中进行配置!

springboot 启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件:

优先级1:项目路径下的config文件夹配置文件

优先级2:项目路径下配置文件

优先级3:资源路径下的config文件夹配置文件

优先级4:资源路径下配置文件

优先级由高到底,高优先级的配置会覆盖低优先级的配置;

自动配置原理

**来到 **META-INF/spring.factories
以其中的 HttpEncodingAutoConfiguration 为例分析

spring.http. 在高版本已经弃用

跟进 ServerProperties.class

那么 yaml 中可以写的配置即为

小结:

xxxxAutoConfigurartion:自动配置类

xxxxProperties: 配置属性类

– debug: true 查看生效的自动配置类


4、SpringBoot Web 开发

4.1 静态资源

4.1.1 静态资源映射规则

WebMvcAutoConfiguration -> EnableWebMvcConfiguration -> addResourceHandlers

Webjars本质就是以jar包的方式引入静态资源

https://www.webjars.org/

要使用jQuery,只要要引入jQuery对应版本的pom依赖即可

另一种规则:/**

WebProperties -> getStaticLocations -> staticLocations -> CLASSPATH_RESOURCE_LOCATIONS ->


优先级:resources > static > public

4.1.2 首页

静态资源文件夹下的所有 index.html 页面

跟进 getWelcomePage()

4.2 Thymeleaf模板引擎

https://www.thymeleaf.org/

https://github.com/thymeleaf/thymeleaf

引入依赖

Thymeleaf的自动配置类:ThymeleafProperties

那么只要在 templates 中写 .html 页面就可以完成 Thymeleaf 模板

4.2.1 Thymeleaf 语法学习

https://www.thymeleaf.org/documentation.html

yaml 配置:

th 属性

  1. th:text :设置当前元素的文本内容,相同功能的还有th:utext,两者的区别在于前者不会转义html标签,后者会。优先级不高:order=7
  2. th:value:设置当前元素的value值,类似修改指定属性的还有th:src,th:href。优先级不高:order=6
  3. th:each:遍历循环元素,和th:text或th:value一起使用。注意该属性修饰的标签位置,详细往后看。优先级很高:order=2
  4. th:if:条件判断,类似的还有th:unless,th:switch,th:case。优先级较高:order=3
  5. th:insert:代码块引入,类似的还有th:replace,th:include,三者的区别较大,若使用不恰当会破坏html结构,常用于公共代码块提取的场景。优先级最高:order=1
  6. th:fragment:定义代码块,方便被th:insert引用。优先级最低:order=8
  7. th:object:声明变量,一般和*{}一起配合使用,达到偷懒的效果。优先级一般:order=4
  8. th:attr:修改任意属性,实际开发中用的较少,因为有丰富的其他th属性帮忙,类似的还有th:attrappend,th:attrprepend。优先级一般:order=5

标准表达式语法

  • Simple expressions:
    • Variable Expressions: **${...}**
    • Selection Variable Expressions: ***{...}**
    • Message Expressions: **#{...}**
    • Link URL Expressions: **@{...}**
    • Fragment Expressions: **~{...}**
~{…} 代码块表达式
  • 推荐:~{templatename::fragmentname}
  • 支持:~{templatename::#id}

templatename:模版名,Thymeleaf会根据模版名解析完整路径:/resources/templates/templatename.html,要注意文件的路径。

fragmentname:片段名,Thymeleaf通过th:fragment声明定义代码块,即:th:fragment="fragmentname"

id:HTML的id选择器,使用时要在前面加上#号,不支持class选择器。

#{…} 消息表达式
@{…} 链接表达式

链接表达式好处:不管是静态资源的引用,form表单的请求,凡是链接都可以用@{…} 。这样可以动态获取项目路径,即便项目名变了,依然可以正常访问。

链接表达式结构:

  • 无参:@{/xxx}
  • 有参:@{/xxx(k1=v1,k2=v2)} 对应url结构:xxx?k1=v1&k2=v2
  • 引入本地资源:@{/项目本地的资源路径}
  • 引入外部资源:@{/webjars/资源在jar包中的路径}
${…}变量表达式

变量表达式功能:

  • 可以获取对象的属性和方法
  • 可以使用ctx,vars,locale,request,response,session,servletContext内置对象
  • 可以使用dates,numbers,strings,objects,arrays,lists,sets,maps等内置方法(重点介绍)

常用的内置对象:

  • ctx :上下文对象。
  • vars :上下文变量。
  • locale:上下文的语言环境。
  • request:(仅在web上下文)的 HttpServletRequest 对象。
  • response:(仅在web上下文)的 HttpServletResponse 对象。
  • session:(仅在web上下文)的 HttpSession 对象。
  • servletContext:(仅在web上下文)的 ServletContext 对象

常用的内置方法:

  • strings:字符串格式化方法,常用的Java方法它都有。比如:equals,equalsIgnoreCase,length,trim,toUpperCase,toLowerCase,indexOf,substring,replace,startsWith,endsWith,contains,containsIgnoreCase等
  • numbers:数值格式化方法,常用的方法有:formatDecimal等
  • bools:布尔方法,常用的方法有:isTrue,isFalse等
  • arrays:数组方法,常用的方法有:toArray,length,isEmpty,contains,containsAll等
  • lists,sets:集合方法,常用的方法有:toList,size,isEmpty,contains,containsAll,sort等
  • maps:对象方法,常用的方法有:size,isEmpty,containsKey,containsValue等
  • dates:日期方法,常用的方法有:format,year,month,hour,createNow等
*{…} 选择变量表达式

4.3 MVC自动配置原理

https://springdoc.cn/spring-boot/web.html#web.servlet