農(nóng)歷鼠年馬上就過去了,我個人也希望在2021有一個好的開始,所以2021年打算通過看一本SpringBoot的全棧開發(fā)教材來重新再認(rèn)識一下SpringBoot,當(dāng)下其已經(jīng)成為了Java界最為流行的后端應(yīng)用開發(fā)框架,通過學(xué)習(xí)這本書也是想讓自己在框架的部分稍微精進(jìn)一些,同時也把自己以前所學(xué)的一些雜七雜八的SpringBoot知識重新整合一下,這邊文章應(yīng)該會長期更新,只不過可能不會太及時,我也是看一點(diǎn)學(xué)一點(diǎn),如果大家有需要指教的也可以一起交流,畢竟寫學(xué)習(xí)筆記也是學(xué)習(xí)的一個好的基礎(chǔ)。
第一章 SpringBoot入門
1.1 SpringBoot簡介
SpringBoot目前的最新版本是2.3.5.RELEASE,在Spring官網(wǎng)可以查到所有版本,推薦后綴是release的穩(wěn)定版,基于學(xué)習(xí)的目的我個人是比較喜歡用最新版本的詳情查看Spring官網(wǎng)版本列舉如下圖所示:

GA后綴就是最新的版本,在項目中引入就可以了,所以我選用的就是2.4.2
1.2 開發(fā)第一個SpringBoot程序
我經(jīng)??吹酱笊袷褂胑clipse的,所以作為菜鳥主要記錄一下用IDEA創(chuàng)建SpringBoot項目
創(chuàng)建項目開始選擇的Spring初始化器,記得選好SDK,通?;蛘呋径际荍ava8。

需要聯(lián)網(wǎng)到官網(wǎng)下載最新的依賴即可,創(chuàng)建之前還需要填寫一些項目信息包括項目描述和打包方式等等,按照正常SpringBoot的情況寫就可以,創(chuàng)建完之后在setting中修改maven配置文件和本地倉庫,然后等待項目加載完成就行。
新創(chuàng)建的SpringBoot項目pom文件里都會默認(rèn)繼承SpringBoot父依賴,然后里邊就是最新的SpringBoot版本,但是這是作為一般模塊來用,一般我們做項目的話會優(yōu)先創(chuàng)建父工程,所以parent標(biāo)簽引入SpringBoot父依賴就不合適了,所以采用的依賴引入方式都是
<properties>
<java.version>1.8</java.version>
<springboot.version>2.3.5.RELEASE</springboot.version>
<lombok.version>1.18.16</lombok.version>
</properties>
<!--引入SpringBoot父依賴的方式-->
<dependencies>
<!--springboot總依賴-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${springboot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--springbootweb-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${springboot.version}</version>
</dependency>
<!--springboottest-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>${springboot.version}</version>
</dependency>
<!--lombok-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
</dependency>
</dependencies>
第一行就是直接引入SpringBoot的父依賴,type和scope的標(biāo)簽都是固定的,這種寫法可以讓我們引入SpringBoot以外的其他父依賴比如SpringCloud或者SpringCloud Alibaba等等,然而一個父依賴的標(biāo)簽只能引入一種父依賴
另外有一點(diǎn)需要注意:
<dependencyManagement>
<dependencies>
</dependencies>
</dependencyManagement>
如果我們把所有的依賴都包在dependencies標(biāo)簽內(nèi)那么整體就成了一個聲明式的依賴管理,一般父項目的pom文件中就是這么聲明依賴的,而本身父項目是不會導(dǎo)入依賴,只是聲明依賴版本,上文的properties標(biāo)簽就是統(tǒng)一聲明依賴版本管理。
項目運(yùn)行只需要執(zhí)行application類的main方法即可。
第二章 SpringBoot基礎(chǔ)配置
2.1 不使用spring-boot-stater-parent
這個就是上文講過的直接導(dǎo)入父項目的依賴而不是使用parent標(biāo)簽。
2.2 @Spring BootApplication
一個標(biāo)注在啟動類上的注解,通過標(biāo)注可以啟動SpringBoot應(yīng)用。
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}
這個組合注解由3個注解組成,第一個表示配置類,第二個表示自動配置,第三個表示包掃描,也就是可以把我們在pom文件中的依賴和properties或者yml中的配置進(jìn)行調(diào)用然后順利啟動程序。
2.3 定制banner
程序啟動的時候在控制臺打印的Spring標(biāo)志是可以替換的,可以在resources目錄下新建一個banner.txt,如圖

在文件中寫上想要的banner就行,附帶一個生成banner的網(wǎng)址banner生成
2.4 容器配置
一般SpringBoot自帶Tomcat,也是web開發(fā)里最常用的web容器,將web包直接放入Tomcat就可以運(yùn)行程序,SpringBoot為了簡化開發(fā)在web依賴中自帶有Tomcat,我們也可以在properties文件里進(jìn)行配置,關(guān)于配置文件后續(xù)再講。
server.servlet.context-path=/jump
server.port=2021
server.tomcat.uri-encoding=utf-8
一般常用的是配置端口號也就是Tomcat的運(yùn)行端口還有就是項目的訪問路徑,注意前面加上/不然會報錯,對于項目的訪問路徑其實(shí)配置的就是啟動項目后輸入IP、端口號然后加上訪問路徑再去訪問接口。
2.5 Properties配置
作為一個快速開發(fā)的Java腳手架帶給我們最直接的視覺變化就是配置的精簡,只需要很少的注解或者是一個配置文件即可,注解是Java一個非常神奇的存在,很多框架借助注解的特點(diǎn)可以讓我們的開發(fā)變得非常簡便。
目前SpringBoot的版本使用兩種配置文件 *.properties和 *.yml,剛初始化好的一個SpringBoot項目會幫我們自動生成properties配置文件,你也可以把它修改成properties后綴的配置文件。
2.6 配置文件的位置

如圖所示,如果4個位置都有propertie配置文件,加載的順序是1~4逐漸降低
配置文件一般寫在resources目錄下,properties文件的語法如下:
book.name=三國演義
book.autho=羅貫中
book.price=30
可以使用如下方法使用自定義的配置
@Component
@ConfigurationProperties(prefix ="book")
public class Book {
private String name;
private String author;
private Float price;
//省略 getter/setter
}
@ConfigurationProperties注解可以把自定義的屬性加載到一個類中,然后再用@Component注解注入到IOC容器中。
2.7 YAML配置
yml文件也是常用的配置文件格式,之所以用這種是因?yàn)樵谝氲絁ava類的配置比較方便。
server:
port: 2021
servlet:
context-path: /jump
tomcat:
uri-encoding: utf-8
以上是yml的常規(guī)配置操作,每一級別的配置都是換行前邊加至少一個空格并且后邊加上冒號,冒號后必須跟著一個空格。
以上是關(guān)于yml文件的簡單配置,當(dāng)我們需要在文件中自定義配置的時候也即復(fù)雜配置的時候yml相比properties的優(yōu)勢就顯示出來了。例如:
senior:
name: 和諧福
age: 20
id: 2
student:
- column: 1
address: 重慶
- column: 2
address: 杭州
favorite:
- 籃球
- 足球
- 羽毛球
上圖是yml文件的自定義配置,同一級別的配置前面的空格需要保持一致,“student”屬性可以配置成對象,我們也可以把student中的屬性加入到一個Java類中,如圖:
package com.senior.study.jumpdown.config;
import lombok.Data;
import org.springframework.stereotype.Component;
/**
* @author bjl_m
*/
@Component
@Data
/**
* @author 白紀(jì)良
*/
public class StudentProperties {
private Integer column;
private String address;
}
需要加上@Component來注冊到IOC容器中,需要注意的是,“column”前面的“-”表示一個元素,如果“column”前面有一個“-”但是下面的address沒有那么說明整體是一個元素,也可以是一個對象,如上圖的配置一個加上兩個“-”那么說明“student”屬性配置成一個對象類型的集合,并且其中包含有2個元素。注意“column”下面的屬性不能再有“-”,如果有那就是兩個對象的兩個屬性注入。配置之后的效果如下:

我們也可以把所有的配置都注冊成為一個Java類。
注入的Java類代碼如下:
package com.senior.study.jumpdown.config;
import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.List;
/**
* @author bjl_m
*/
@Component
@ConfigurationProperties(prefix = "senior")
@Data
public class SeniorProperties {
private Integer id;
private String name;
private Integer age;
private List<String> favorite;
private List<StudentProperties> student;
@Autowired
public void setStudent(List<StudentProperties> student) {
this.student = student;
}
}
@ConfigurationProperties(prefix = "senior")屬性senior開頭的自定義屬性,里面的屬性分別對應(yīng)該配置類的所有自定義內(nèi)容??梢钥吹健癴avorite”定義為了集合,是字符串類型所以需要在每個元素上添加“-”。
最后使用@Autowired使用setter注入“student”對象,也是集合形式,如上圖StudentProperties 類所示,這就是yml文件自定義配置的代碼注入方式,這種方式在我們需要配置集合和數(shù)組的時候很常用。
還有另外一種方式可以注入自定義配置比如,@ProprtySource
package com.senior.study.jumpdown.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;
@Component
@PropertySource(value = "classpath:bjl.properties",encoding = "UTF-8")
@Data
@ConfigurationProperties(prefix = "bjl")
public class BjlProperties {
private String name;
private Integer age;
}
@PropertySource注解的使用很簡單,當(dāng)我們自定義一個配置文件,也就是命名不是application而是別的什么,如果直接用@ConfigurationProperties這個注解是無效的,所以需要用到@PropertySource注解整體注入到一個自定義的Java類中。但是這個注解對yml的支持不夠所以我們在自定義配置文件的時候最好用properties后綴
2.8 Profile配置
這個功能主要是用來多環(huán)境配置文件的切換,一般我們需要在項目里創(chuàng)建數(shù)個配置文件,如圖

命名的規(guī)則是application-{dev(pro、test)}.yml(properties),一般需要遵守這個命名格式,然后我們要新建一個application.yml或者是application.properties文件,在當(dāng)中啟用Profile的配置
spring:
profiles:
active: pro
第三章 SpringBoot整合視圖層技術(shù)
3.1 整合Thymeleaf
Thymeleaf是Freemaker的比較好的替代品,作為前端引擎也比較適合后端工程師進(jìn)行開發(fā)。
引入themeleaf需要引入springboot啟動器,還需要web依賴,此處不再贅述。
<properties>
<thymeleaf.version>2.3.4.RELEASE</thymeleaf.version>
</properties>
<!--thymeleaf-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<version>${thymeleaf.version}</version>
</dependency>
第二步我們需要在yml文件進(jìn)行配置
# thymeleaf配置
spring:
thymeleaf:
# 是否開啟緩存(默認(rèn))
cache: true
# 檢查模板是否存在(默認(rèn))
check-template: true
# 模板位置是否存在(默認(rèn))
check-template-location: true
# 模板文件編碼
encoding: UTF-8
servlet:
# 文檔類型配置
content-type: text/html
# 頁面后綴
suffix: .html
# 前綴
prefix: classpath:/templates/
說明一下前綴后綴,前綴的配置是默認(rèn)的,我們可以在resources目錄下新建templates文件夾新建一個html頁面,后綴需要配置.html,前綴默認(rèn)配置也即默認(rèn)回到根目錄的templates下找到html頁面。
簡單新建一個實(shí)體類
package com.senior.study.jumpdown.domain;
import lombok.Data;
/**
* @author bjl_m
*/
@Data
public class Book {
private Integer id;
private String name;
}
和控制器controller
package com.senior.study.jumpdown.controller;
import com.senior.study.jumpdown.domain.Book;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.servlet.ModelAndView;
/**
* @author bjl_m
*/
@RestController
@RequestMapping("books")
public class BookController {
/**
* springboot整合thymeleaf
* @return
*/
@GetMapping("book")
public ModelAndView book(){
Book book = new Book();
book.setName("淘氣包馬小跳");
book.setId(1);
System.out.println(book);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject(book);
modelAndView.setViewName("books");
return modelAndView;
}
}
這里注意的是我們返回ModelAndView 對象,它可以直接將數(shù)據(jù)返回到頁面并且返回自定義頁面。

這樣的話基本整合完成。
3.2 整合Freemaker
Freemarker對比thymeleaf是相對古老的視圖引擎,springboot對于freemarker也有了很完善的支持。首先還是引入依賴。
<properties>
<freemarker.version>2.3.4.RELEASE</freemarker.version>
</properties>
<!--freemarker-->
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>${freemarker.version}</version>
</dependency>
</dependencies>
還需要web依賴,此處不再贅述。
接下來對Freemaker進(jìn)行配置
# freemarker配置
# httpservletrequest的屬性是否可以覆蓋controller中的同名項
freemarker:
allow-request-override: false
# httpsession的屬性是否可以覆蓋controller中的同名項
allow-session-override: false
# 是否開啟緩存
cache: false
# 模板編碼
charset: UTF-8
# 是否檢查模板位置
check-template-location: true
# 文檔類型配置
content-type: text/html
# 是否將httpservletrequest中的屬性加入到model中
expose-request-attributes: false
# 是否將httpsession中的屬性添加到model中
expose-session-attributes: false
# 后綴
suffix: .ftl
# 模板文件位置 前綴
template-loader-path: classpath:/templates/
注意,在最底下的前綴配置中跟thymeleaf是一樣的,都是從項目根目錄下的templates找到模板。
/**
* springboot整合freemarker
* @return
*/
@GetMapping("book2")
public ModelAndView bookFreeMarker(){
Book book = new Book();
book.setName("中國味道");
book.setId(2);
System.out.println(book);
ModelAndView modelAndView = new ModelAndView();
modelAndView.addObject(book);
modelAndView.setViewName("books-freemarker");
return modelAndView;
}
我們在controller新建一個跳轉(zhuǎn)方法,內(nèi)容跟thymeleaf基本一致,之后再新建freemaker模板。
<!DOCTYPE html>
<html lang="en" >
<head>
<meta charset="UTF-8">
<title>books</title>
</head>
<body>
thanks books-freemarker
<a>${book.id}</a>
<a>${book.name}</a>
</body>
</html>
這里去掉了第二行對thymeleaf的引入,在a標(biāo)簽中也去掉了專有的th語法,同樣是用${}接收傳輸對象。效果如下:

第四章 SpringBoot整合Web開發(fā)
4.1 返回JSON數(shù)據(jù)
json交互是目前前后端分離開發(fā)模式的通用方式,springMVC提供了默認(rèn)的方式比如@ResponseBody注解,用于方法時該方法的返回值會自動轉(zhuǎn)換為json,用于類上時會默認(rèn)整個類的所有方法返回值自動轉(zhuǎn)化為json,springMVC還有一種復(fù)合注解,@RestController,它等于@Controller+@ResponseBody。
另外除了springMVC自帶的還有一些第三方j(luò)son框架可供選擇。比如阿里巴巴的Fastjson或者谷歌的Gson,一般項目中使用fastjson比較多,目的也是為了對json進(jìn)行轉(zhuǎn)化或者是字符串和json之間的互轉(zhuǎn)等等,那我推薦一個國內(nèi)的活躍框架hutool。hutool開源框架
4.2 靜態(tài)資源訪問
第五章 SpringBoot整合持久層技術(shù)
5.1 整合JdbcTemplate
JdbcTemplate是spring封裝的操作數(shù)據(jù)庫的操作API,類似于mybatis或者是springdatajpa,我們先嘗試用springboot整合jdbctemplate.
首先引入jdbc的依賴
<properties>
<mysql.version>8.0.21</mysql.version>
<druid.version>1.2.5</druid.version>
<springboot.version>2.3.5.RELEASE</springboot.version>
</properties>
<!--dependenciesmanagement作用:加上這個標(biāo)簽里面的依賴就成為了父pom
只是聲明依賴,由子類引入具體依賴,但是不加這個標(biāo)簽就是引入springboot的另一種形式,
等價于用parent標(biāo)簽引入springboot父項目-->
<!-- <dependencyManagement>-->
<dependencies>
<!--springbootweb-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>${springboot.version}</version>
</dependency>
<!--springboot整合jdbcTemplate-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
<version>${springboot.version}</version>
</dependency>
<!--springboot整合mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
<scope>runtime</scope>
</dependency>
<!--阿里巴巴數(shù)據(jù)連接池-->
<!-- <dependency>-->
<!-- <groupId>com.alibaba</groupId>-->
<!-- <artifactId>druid-spring-boot-starter</artifactId>-->
<!-- <version>${druid.version}</version>-->
<!-- </dependency>-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
</dependencies>
<!-- </dependencyManagement>-->
需要引入web的基礎(chǔ)依賴、springboot封裝的jdbc啟動器、mysql依賴和阿里巴巴數(shù)據(jù)庫連接池,這里注意連接池沒有使用springboot啟動器而使用普通的maven依賴。
但是如果我們直接繼承springboot父依賴?yán)纾?/p>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.3.5.RELEASE</version>
</parent>
就可以使用springboot的阿里巴巴數(shù)據(jù)庫連接池啟動器
<!--阿里巴巴數(shù)據(jù)連接池-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
</dependency>
也就是說如果我們使用引入springbootdependencies方式使用springboot那不能直接使用Druid的springboot啟動器。