1. Spring Boot概述
目標(biāo):了解Spring Boot是什么蝠筑,有什么作用
小結(jié):
Spring Boot是一個(gè)便捷搭建 基于spring工程的腳手架隘梨;作用是幫助開發(fā)人員快速搭建大型的spring 項(xiàng)目单寂。簡化工程的配置猎荠,依賴管理铺呵;實(shí)現(xiàn)開發(fā)人員把時(shí)間都集中在業(yè)務(wù)開發(fā)上。
2. Spring Boot入門
目標(biāo):能夠使用Spring Boot搭建項(xiàng)目
分析:
需求:可以在瀏覽器中訪問http://localhost:8080/hello輸出一串字符
實(shí)現(xiàn)步驟:
-
創(chuàng)建工程井濒;
看到這里很多同學(xué)會有疑惑灶似,前面說傳統(tǒng)開發(fā)的問題之一就是依賴管理混亂,怎么這里我們還需要管理依賴呢?難道
Spring Boot不幫我們管理嗎?
別著急瑞你,現(xiàn)在我們的項(xiàng)目與Spring Boot還沒有什么關(guān)聯(lián)酪惭。Spring Boot提供了一個(gè)名為spring-boot-starter-parent 的工程,里面已經(jīng)對各種常用依賴(并非全部)的版本進(jìn)行了管理者甲,我們的項(xiàng)目需要以這個(gè)項(xiàng)目為父工程春感,這樣我們 就不用操心依賴的版本問題了,需要什么依賴虏缸,直接引入坐標(biāo)即可!
- 添加依賴(啟動(dòng)器依賴鲫懒,spring-boot-starter-web);
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
為了讓Spring Boot幫我們完成各種自動(dòng)配置刽辙,我們必須引入Spring Boot提供的自動(dòng)配置依賴窥岩,我們稱為 啟動(dòng)器 。因
為我們是web項(xiàng)目宰缤,這里我們引入web啟動(dòng)器颂翼,在 pom.xml 文件中加入如下依賴:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
需要注意的是,我們并沒有在這里指定版本信息慨灭。因?yàn)镾pring Boot的父工程已經(jīng)對版本進(jìn)行了管理了朦乏。 這個(gè)時(shí)候,我們會發(fā)現(xiàn)項(xiàng)目中多出了大量的依賴缘挑。
那些依賴都是Spring Boot根據(jù) spring-boot-starter-web 這個(gè)依賴自動(dòng)引入的集歇,而且所有的版本都已經(jīng)管理好,不 會出現(xiàn)沖突语淘。
如果我們想要修改Spring Boot項(xiàng)目的jdk版本诲宇,只需要簡單的添加以下屬性即可,如果沒有需求惶翻,則不添加姑蓝。同樣的
在 pom.xml 文件中添加如下:
<properties>
<java.version>1.8</java.version>
</properties>
完整版的pom.xml文件:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>Springboot</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<java.version>1.8</java.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>
-
創(chuàng)建啟動(dòng)類;
Spring Boot項(xiàng)目通過main函數(shù)即可啟動(dòng)吕粗,我們需要?jiǎng)?chuàng)建一個(gè)啟動(dòng)類:
編寫 springboot\src\main\java\com\nono\Application.java 如下:
package com.nono;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
- 創(chuàng)建處理器Controller纺荧;
package com.nono.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
//相當(dāng)于@Controller+@ResponseBody兩個(gè)注解的結(jié)合,返回json數(shù)據(jù)不需要在方法前面加@ResponseBody注解了颅筋,但使用@RestController這個(gè)注解宙暇,就不能返回jsp,html頁面,視圖解析器無法解析jsp,html頁面
@RestController
public class HellowController {
@GetMapping("hello")
public String hello(){
return "hello,spring boot";
}
}
Spring的復(fù)雜性不是來自于它處理的對象议泵,而是來自于自身占贫,不斷演進(jìn)發(fā)展的Spring會帶來時(shí)間維度上復(fù)雜性,比如SpringMVC以前版本的@RequestMapping先口,到了新版本被下面新注釋替代型奥,相當(dāng)于增加的選項(xiàng):
@GetMapping
@PostMapping
@PutMapping
@DeleteMapping
@PatchMapping
從命名約定我們可以看到每個(gè)注釋都是為了處理各自的傳入請求方法類型瞳收,即@GetMapping用于處理請求方法的GET類型,@ PostMapping用于處理請求方法的POST類型等厢汹。
如果我們想使用傳統(tǒng)的@RequestMapping注釋實(shí)現(xiàn)URL處理程序螟深,那么它應(yīng)該是這樣的:
@RequestMapping(value = "/get/{id}", method = RequestMethod.GET)
新方法可以簡化為:
@GetMapping("/get/{id}")
-
測試
接下來,運(yùn)行main函數(shù)烫葬,查看控制臺:
并且可以看到監(jiān)聽的端口信息:
1)監(jiān)聽的端口是8080
2)SpringMVC的項(xiàng)目路徑是:空
3)/hello 路徑已經(jīng)映射到了 HelloController 中的 hello() 方法
打開頁面訪問:http://localhost:8080/hello
小結(jié):
Spring Boot工程可以通過添加啟動(dòng)器依賴和創(chuàng)建啟動(dòng)引導(dǎo)類實(shí)現(xiàn)快速創(chuàng)建web工程界弧。
spring-boot-starter-web默認(rèn)的應(yīng)用服務(wù)器端口是8080
3. Java代碼方式配置
目標(biāo):可以使用@Value獲取配置文件配置項(xiàng)并結(jié)合@Bean注冊組件到Spring
分析:
需求:使用Java代碼配置數(shù)據(jù)庫連接池,并可以在處理器中注入并使用
步驟:
- 添加依賴厘灼;
在 pom.xml 文件中添加Druid連接池依賴如下
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
- 創(chuàng)建數(shù)據(jù)庫夹纫;
- 創(chuàng)建數(shù)據(jù)庫連接參數(shù)的配置文件jdbc.properties;
然后在項(xiàng)目中創(chuàng)建 springboot\src\main\resources\jdbc.properties 文件设凹,內(nèi)容如下
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/nono
jdbc.username=root
jdbc.password=123456
- 創(chuàng)建配置類舰讹;
- 改造處理器類注入數(shù)據(jù)源并使用
編寫 springboot\src\main\java\com\nono\config\JdbcConfig.java 如下
package com.nono.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
@Configuration
@PropertySource("classpath:jdbc.properties")
public class JdbcConfig {
@Value("${jdbc.driverClassName}")
String driverClassName;
@Value("${jdbc.url}")
String url;
@Value("${jdbc.username}")
String username;
@Value("${jdbc.password}")
String password;
@Bean
public DataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(driverClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
return dataSource;
}
}
在 HelloController 中注入DataSource進(jìn)行測試,改造代碼如下:
package com.nono.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.sql.DataSource;
@RestController
public class HellowController {
@Autowired
private DataSource dataSource;
@GetMapping("hello")
public String hello(){
System.out.println("DataSource = "+dataSource);
return "hello,spring boot";
}
}
然后打斷點(diǎn)闪朱,Debug運(yùn)行并查看:
屬性注入成功了!
小結(jié):
4. Spring Boot屬性注入方式
目標(biāo):能夠使用@ConfigurationProperties實(shí)現(xiàn)Spring Boot配置文件配置項(xiàng)讀取和應(yīng)用
分析:
需求:將配置文件中的配置項(xiàng)讀取到一個(gè)對象中月匣;
實(shí)現(xiàn):可以使用Spring Boot提供的注解@ConfigurationProperties,該注解可以將Spring Boot的配置文件(默認(rèn)必須為application.properties或application.yml)中的配置項(xiàng)讀取到一個(gè)對象中奋姿。
實(shí)現(xiàn)步驟:
- 創(chuàng)建配置項(xiàng)類JdbcProperties類锄开,在該類名上面添加@ConfigurationProperties;
- 將jdbc.properties修改名稱為application.properties称诗;
- 將JdbcProperties對象注入到JdbcConfig萍悴;
- 測試
屬性文件的名稱有變化,默認(rèn)的文件名必須是:application.properties或application.yml
在上面的案例中寓免,我們實(shí)驗(yàn)了java配置方式癣诱。不過屬性注入使用的是@Value注解。這種方式雖然可行袜香,但是不夠強(qiáng) 大撕予,因?yàn)樗荒茏⑷牖绢愋椭怠?br>
在Spring Boot中,提供了一種新的屬性注入方式蜈首,支持各種java基本數(shù)據(jù)類型及復(fù)雜類型的注入实抡。
1)新建 heima-springboot\src\main\java\com\nono\config\JdbcProperties.java ,用于進(jìn)行屬性注 入:
package com.nono.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
@ConfigurationProperties(prefix = "jdbc")
public class JdbcProperties {
private String url;
private String driverClassName;
private String username;
private String password;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
在類上通過@ConfigurationProperties注解聲明當(dāng)前類為屬性讀取類 prefix="jdbc" 讀取屬性文件中欢策,前綴為jdbc的值吆寨。
在類上定義各個(gè)屬性,名稱必須與屬性文件中 jdbc. 后面部分一致 需要注意的是踩寇,這里我們并沒有指定屬性文件的地址啄清,所以我們需要把jdbc.properties名稱改為
application.properties,這是Spring Boot默認(rèn)讀取的屬性文件名:
【注意】如果出現(xiàn)如下提示姑荷,項(xiàng)目也可以運(yùn)行;
如果要去掉上述的提示盒延,則可以在 pom.xml 文件中添加如下依賴:
<dependency>
<groupId> org.springframework.boot </groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<!--不傳遞依賴-->
<optional>true</optional>
</dependency>
2)將 JdbcConfig 類原來全部注釋掉或刪除,修改為如下內(nèi)容:
package com.nono.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
@Configuration
@EnableConfigurationProperties(JdbcProperties.class)
public class JdbcConfig {
@Bean
public DataSource dataSource(JdbcProperties jdbc){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName(jdbc.getDriverClassName());
dataSource.setUrl(jdbc.getUrl());
dataSource.setUsername(jdbc.getUsername());
dataSource.setPassword(jdbc.getPassword());
return dataSource;
}
}
通過 @EnableConfigurationProperties(JdbcProperties.class) 來聲明要使用 JdbcProperties 這個(gè)類的 對象
然后要使用配置的話;可以通過以下方式注入JdbcProperties:
3)測試結(jié)果;與前面的測試一樣的鼠冕。
大家會覺得這種方式似乎更麻煩了添寺,事實(shí)上這種方式有更強(qiáng)大的功能,也是Spring Boot推薦的注入方式懈费。與@Value 對比關(guān)系:
優(yōu)勢:
Relaxed binding:松散綁定
1计露、不嚴(yán)格要求屬性文件中的屬性名與成員變量名一致。支持駝峰憎乙,中劃線票罐,下劃線等等轉(zhuǎn)換,甚至支持對象 引導(dǎo)泞边。比如:user.friend.name:代表的是user對象中的friend屬性中的name屬性该押,顯然friend也是對 象。@value注解就難以完成這樣的注入方式阵谚。
2蚕礼、meta-data support:元數(shù)據(jù)支持,幫助IDE生成屬性提示(寫開源框架會用到)梢什。
更優(yōu)雅的注入:
事實(shí)上奠蹬,如果一段屬性只有一個(gè)Bean需要使用,我們無需將其注入到一個(gè)類(JdbcProperties嗡午,將該類上的所有注 解去掉)中囤躁。而是直接在需要的地方聲明即可;再次修改 JdbcConfig 類為如下代碼:
package com.nono.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import javax.sql.DataSource;
@Configuration
public class JdbcConfig {
@Bean
@ConfigurationProperties(prefix = "jdbc")// 聲明要注入的屬性前綴,Spring Boot會自動(dòng)把相關(guān)屬性通過set方法注入到DataSource中
public DataSource dataSource(){
return new DruidDataSource();
}
}
我們直接把@ConfigurationProperties(prefix = "jdbc")聲明在需要使用的@Bean的方法上荔睹,然后Spring Boot就會自動(dòng)調(diào)用這個(gè)Bean(此處是DataSource)的set方法狸演,然后完成注入。使用的前提是:該類必須有對應(yīng)屬 性的set方法!
小結(jié):
5. 多個(gè)yml文件配置
目標(biāo):可以將多個(gè)yml文件在application.yml文件中配置激活
分析:
yaml與properties配置文件除了展示形式不相同以外应媚,其它功能和作用都是一樣的严沥;在項(xiàng)目中原路的讀取方式不需要改變。
1)yml配置文件的特征:
- 樹狀層級結(jié)構(gòu)展示配置項(xiàng)中姜;
- 配置項(xiàng)之間如果有關(guān)系的話需要分行空兩格消玄;
- 配置項(xiàng)如果有值的話,那么需要在
:
之后空一格再寫配置項(xiàng)值丢胚;
將application.properties配置文件修改為application.yml的話:
jdbc:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/nono
username: root
password: 123456
key:
abc: cba
def:
- g
- h
- j
2)多個(gè)yml配置文件翩瓜;在spring boot中是被允許的。這些配置文件的名稱必須為application-***.yml携龟,并且這些配置文件必須要在application.yml配置文件中激活之后才可以使用兔跌。
創(chuàng)建 application-abc.yml 文件如下:
nono:
url: http://www.nono.cn
創(chuàng)建 application-def.yml 文件如下:
gao:
url: http://www.gao.cn
在多個(gè)配置文件時(shí),需要將這些文件在application.yml文件中進(jìn)行激活:
#激活配置文件;需要指定其它的配置文件名稱
spring:
profiles:
active: abc,def
修改HellowController獲取配置文件中的值
package com.nono.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.sql.DataSource;
@RestController
public class HellowController {
@Value("${nono.url}")
private String nonourl;
@Value("${gao.url}")
private String gaourl;
@Autowired
private DataSource dataSource;
@GetMapping("hello")
public String hello(){
System.out.println(nonourl);
System.out.println(gaourl);
System.out.println("DataSource = "+dataSource);
return "hello,spring boot";
}
}
3)如果properties和yml配置文件同時(shí)存在在spring boot項(xiàng)目中峡蟋;那么這兩類配置文件都有效坟桅。在兩個(gè)配置文件中如果存在同名的配置項(xiàng)的話會以properties文件的為主华望。
小結(jié):
6. 自動(dòng)配置原理
目標(biāo):了解Spring Boot項(xiàng)目的配置加載流程
小結(jié):
(具體看pdf)
- 在
META-INF\spring.fatories
文件中定義了很多自動(dòng)配置類;可以根據(jù)在pom.xml文件中添加的 啟動(dòng)器依賴自動(dòng)配置組件 - 通過如下流程可以去修改application配置文件仅乓,改變自動(dòng)配置的組件默認(rèn)參數(shù)
springboot實(shí)戰(zhàn):
7. lombok應(yīng)用
我們編寫pojo時(shí)赖舟,經(jīng)常需要編寫構(gòu)造函數(shù)和getter、setter方法夸楣,屬性多的時(shí)候宾抓,就非常浪費(fèi)時(shí)間,使用lombok插件
可以解決這個(gè)問題:
在IDEA中安裝lombok插件;不安裝插件在IDEA中使用lombok的注解雖然編譯能通過豫喧,但是源碼會報(bào)錯(cuò)石洗。所以為了 讓IDEA更好的辨別lombok注解則才安裝插件。
需要在maven工程中的 文件引入依賴:
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
然后可以在Bean上使用:
@Data :自動(dòng)提供getter和setter紧显、hashCode讲衫、equals、toString等方法 @Getter:自動(dòng)提供getter方法
@Setter:自動(dòng)提供setter方法 @Slf4j:自動(dòng)在bean中提供log變量孵班,其實(shí)用的是slf4j的日志功能焦人。
例如;在javabean上加@Data,那么就可以省去getter和setter等方法的編寫重父,lombok插件會自動(dòng)生成花椭。
package com.nono.pojo;
import lombok.Data;
import java.util.Date;
@Data
public class User {
// id
private Long id;
// 用戶名
private String userName;
// 密碼
private String password;
// 姓名
private String name;
// 年齡
private Integer age;
// 性別,1男性房午,2女性 private Integer sex;
// 出生日期
private Date birthday;
// 創(chuàng)建時(shí)間
private Date created;
// 更新時(shí)間
private Date updated;
// 備注
private String note;
}
目標(biāo):使用lombok的注解實(shí)現(xiàn)pojo類的簡化
分析:
使用Spring Boot整合SSM工程矿辽;需要使用到數(shù)據(jù)庫數(shù)據(jù)。
將數(shù)據(jù)庫表數(shù)據(jù)導(dǎo)入到數(shù)據(jù)庫中(springboot_test)郭厌;
-
編寫數(shù)據(jù)庫表對應(yīng)的實(shí)體類袋倔;一般情況下需要編寫get/set/toString等這些方法會耗時(shí)并且會讓實(shí)體類看起來比較臃腫≌勰可以使用lombok插件對實(shí)體類進(jìn)行簡化宾娜。
lombok是一個(gè)插件工具類包;提供了一些注解@Data扇售、@Getter等這些注解去簡化實(shí)體類中的構(gòu)造方法前塔、get/set等方法的編寫。
- 在IDEA中安裝lombok插件承冰;
- 添加lombok對應(yīng)的依賴到項(xiàng)目pom.xml文件华弓;
- 改造實(shí)體類使用lombok注解
小結(jié):
在Bean上使用:
@Data :自動(dòng)提供getter和setter、hashCode困乒、equals寂屏、toString等方法
@Getter:自動(dòng)提供getter方法
@Setter:自動(dòng)提供setter方法
@Slf4j:自動(dòng)在bean中提供log變量,其實(shí)用的是slf4j的日志功能。
8. Spring Boot整合-SpringMVC端口和靜態(tài)資源
雖然默認(rèn)配置已經(jīng)可以使用SpringMVC了迁霎,不過我們有時(shí)候需要進(jìn)行自定義配置吱抚。
可以在 application.yml 文件中配置日志級別控制:
logging:
level:
com.nono: debug
org.springframework: info
修改端口:
查看SpringBoot的全局屬性可知,端口通過以下方式配置:
修改 配置文件考廉,添加如下配置:
server:
port: 80
訪問靜態(tài)資源:
現(xiàn)在频伤,我們的項(xiàng)目是一個(gè)jar工程,那么就沒有webapp芝此,我們的靜態(tài)資源該放哪里呢?
回顧我們在上面看的源碼,有一個(gè)叫做ResourceProperties的類因痛,里面就定義了靜態(tài)資源的默認(rèn)查找路徑:
默認(rèn)的靜態(tài)資源路徑為:
classpath:/META-INF/resources/ classpath:/resources/ classpath:/static/ classpath:/public
只要靜態(tài)資源放在這些目錄中任何一個(gè)婚苹,SpringMVC都會幫我們處理。
我們習(xí)慣會把靜態(tài)資源放在 classpath:/static/ 目錄下鸵膏。我們創(chuàng)建目錄 static 膊升,并且從 資料 文件夾中復(fù)制 itcast.gif 和 test.js 如下:
9.Spring Boot整合-SpringMVC攔截器
目標(biāo):可以在Spring Boot項(xiàng)目中配置自定義SpringMVC攔截器
攔截器不是一個(gè)普通屬性,而是一個(gè)類谭企,所以就要用到j(luò)ava配置方式了廓译。在SpringBoot官方文檔中有這么一段說明:
分析:
- 編寫攔截器(實(shí)現(xiàn)HandlerInterceptor);
- 編寫配置類實(shí)現(xiàn) WebMvcConfigurer债查,在該類中添加各種組件非区;
- 測試
總結(jié):通過實(shí)現(xiàn) WebMvcConfigurer 并添加 @Configuration 注解來實(shí)現(xiàn)自定義部分SpringMvc配置。
- 創(chuàng)建 springboot\src\main\java\com\nono\interceptor\MyInterceptor.java 攔截器盹廷,內(nèi)容 如下:
package com.nono.interceptor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@Slf4j
public class MyInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {
log.debug("這是MyInterceptor攔截器的preHandle方法");
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response,
Object handler, ModelAndView modelAndView) throws Exception {
log.debug("這是MyInterceptor攔截器的postHandle方法");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse
response, Object handler, Exception ex) throws Exception {
log.debug("這是MyInterceptor攔截器的afterCompletion方法");
}
}
- 定義配置類 springboot\src\main\java\com\nono\config\MvcConfig.java 征绸,用于注冊攔截 器,內(nèi)容如下:
package com.nono.config;
import com.nono.interceptor.MyInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class MvcConfig implements WebMvcConfigurer {
/**
* 將攔截器注冊到spring ioc容器 * @return myInterceptor
*/
@Bean
public MyInterceptor myInterceptor(){
return new MyInterceptor();
}
/**
* 重寫該方法;往攔截器鏈添加自定義攔截器 * @param registry 攔截器鏈
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
//通過registry添加myInterceptor攔截器俄占,并設(shè)置攔截器路徑為 /*
registry.addInterceptor(myInterceptor()).addPathPatterns("/*");
}
}
結(jié)構(gòu)如下:
10. Spring Boot整合-事務(wù)和連接池
spring中的jdbc連接和事務(wù)是配置中的重要一環(huán)管怠,在SpringBoot中該如何處理呢?
答案是不需要處理,我們只要找到SpringBoot提供的啟動(dòng)器即可缸榄,在 pom.xml 文件中添加如下依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
當(dāng)然渤弛,不要忘了數(shù)據(jù)庫驅(qū)動(dòng),SpringBoot并不知道我們用的什么數(shù)據(jù)庫甚带,這里我們選擇MySQL;同樣的在 pom.xml 文件中添加如下依賴:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
至于事務(wù)她肯,SpringBoot中通過注解來控制。就是我們熟知的@Transactional 使用的時(shí)候設(shè)置在對應(yīng)的類或方法上 即可鹰贵。
創(chuàng)建 springboot\src\main\java\com\nono\service\UserService.java 業(yè)務(wù)類如下:
package com.nono.service;
import com.nono.pojo.User;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserService {
public User queryById(Long id){ //根據(jù)id查詢
return new User();
}
@Transactional
public void saveUser(User user){ System.out.println("新增用戶...");
}
}
其實(shí)辕宏,在剛才引入jdbc啟動(dòng)器的時(shí)候,SpringBoot已經(jīng)自動(dòng)幫我們引入了一個(gè)連接池:
HikariCP應(yīng)該是目前速度最快的連接池了砾莱,我們看看它與c3p0的對比:
因此瑞筐,我們只需要指定連接池參數(shù)即可;打開 application.yml 添加修改配置如下:
【注意】
把 JdbcConfig 類中的druid的配置刪除或注釋;
在配置完hikari數(shù)據(jù)庫連接池后的 application.yml 文件如下:
啟動(dòng)項(xiàng)目,訪問 http://localhost/hello ;查看后臺輸出,一樣可以在HelloController中獲取到datasource聚假。
目標(biāo):配置Spring Boot自帶默認(rèn)的hikari數(shù)據(jù)庫連接池和使用@Transactional注解進(jìn)行事務(wù)配置
分析:
-
事務(wù)配置
- 添加事務(wù)相關(guān)的啟動(dòng)器依賴块蚌,mysql相關(guān)依賴;
- 編寫業(yè)務(wù)類UserService使用事務(wù)注解@Transactional
-
數(shù)據(jù)庫連接池hikari配置
只需要在application配置文件中指定數(shù)據(jù)庫相關(guān)參數(shù)
小結(jié):
- 事務(wù)配置膘格;只需要添加jdbc啟動(dòng)器依賴
- 數(shù)據(jù)庫連接池使用默認(rèn)的hikari峭范,在配置文件中配置如下:
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/springboot_test
username: root
password: root
11. Spring Boot整合-Mybatis
- SpringBoot官方并沒有提供Mybatis的啟動(dòng)器,不過Mybatis官網(wǎng)自己實(shí)現(xiàn)了瘪贱。在項(xiàng)目的 pom.xml 文件中加入如 下依賴:
<!--mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
- 配置 application.yml 纱控,常用配置如下:
# mybatis配置
mybatis:
# 實(shí)體類別名包路徑
type-aliases-package: com.nono.pojo
# 映射文件路徑
# mapper-locations: classpath:mappers/*.xml
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
- 配置Mapper掃描
需要注意,這里沒有配置mapper接口掃描包菜秦,因此我們需要給每一個(gè)Mapper接口添加 @Mapper 注解甜害,才能被識 別。
@Mapper
public interface UserMapper {
}
或者球昨,我們也可以不加注解尔店,而是在啟動(dòng)類上添加掃描包注解(推薦):
@SpringBootApplication
@MapperScan("com.nono.mapper")
public class Application {
public static void main(String[] args) {
// 啟動(dòng)代碼
SpringApplication.run(Application.class, args);
}
}
以下代碼示例中,我們將采用@MapperScan掃描方式進(jìn)行主慰。
目標(biāo):配置Mybatis在Spring Boot工程中的整合包嚣州,設(shè)置mybatis的實(shí)體類別名,輸出執(zhí)行sql語句配置項(xiàng)
分析:
- 添加啟動(dòng)器依賴共螺;
- 配置Mybatis:實(shí)體類別名包该肴,日志,映射文件等藐不;
- 配置MapperScan
小結(jié):
-
配置mybatis
mybatis: # 實(shí)體類別名包路徑 type-aliases-package: com.nono.pojo # 映射文件路徑 # mapper-locations: classpath:mappers/*.xml configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl ```
設(shè)置啟動(dòng)器類中的mapper掃描
12. Spring Boot整合-通用Mapper
- 通用Mapper的作者也為自己的插件編寫了啟動(dòng)器沙庐,我們直接引入即可。在項(xiàng)目的 pom.xml 文件中加入如下依 賴:
<!--mybatis
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>-->
<!-- 通用mapper -->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
注意:一旦引入了通用Mapper的啟動(dòng)器佳吞,會覆蓋Mybatis官方啟動(dòng)器的功能拱雏,因此需要移除對官方Mybatis啟動(dòng)器 的依賴。
- 編寫UserMapper 無需任何配置就可以使用了底扳。如果有特殊需要铸抑,可以到通用mapper官網(wǎng)查看:https://github.com/abel533/Mappe
r/wiki/3.config
編寫 springboot\src\main\java\com\nono\mapper\UserMapper.java 如下:
package com.itheima.mapper;
import com.itheima.pojo.User;
import tk.mybatis.mapper.common.Mapper;
public interface UserMapper extends Mapper<User> {
}
-
把啟動(dòng)類上的@MapperScan注解修改為通用mapper中自帶的:
- 在User實(shí)體類上加JPA注解
修改 springboot\src\main\java\com\nono\pojo\User.java 如下:
package com.nono.pojo;
import lombok.Data;
import tk.mybatis.mapper.annotation.KeySql;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;
@Data
@Table(name = "tb_user")
public class User {
// id
@Id
@KeySql(useGeneratedKeys = true)
private Long id;
// 用戶名
private String userName;
// 密碼
private String password;
// 姓名
private String name;
// 年齡
private Integer age;
// 性別,1男性衷模,2女性 private Integer sex;
// 出生日期
private Date birthday;
// 創(chuàng)建時(shí)間
private Date created;
// 更新時(shí)間
private Date updated;
// 備注
private String note;
}
package com.nono.service;
import com.nono.mapper.UserMapper;
import com.nono.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User queryById(Long id){
//根據(jù)id查詢
return userMapper.selectByPrimaryKey(id);
}
@Transactional
public void saveUser(User user){
System.out.println("新增用戶...");
userMapper.insertSelective(user);
}
}
package com.nono.controller;
import com.nono.pojo.User;
import com.nono.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import javax.sql.DataSource;
@RestController
public class HellowController {
@Autowired
private UserService userService;
/**
* 根據(jù)id獲取用戶
* @param id 用戶id * @return 用戶
*/
@GetMapping("/user/{id}")
public User queryById(@PathVariable Long id){
return userService.queryById(id);
}
}
目標(biāo):配置通用Mapper組件到Spring Boot項(xiàng)目中并使用Mapper<T>接口
分析:
通用Mapper:可以實(shí)現(xiàn)自動(dòng)拼接sql語句鹊汛;所有的mapper都不需要編寫任何方法也就是不用編寫sql語句≮逡保可以提高開發(fā)效率刁憋。
- 添加啟動(dòng)器依賴;
- 改造UserMapper繼承Mapper<User>木蹬;
- 修改啟動(dòng)引導(dǎo)類Application中的Mapper掃描注解至耻;
- 修改User實(shí)體類添加jpa注解;
- 改造UserService實(shí)現(xiàn)業(yè)務(wù)功能;
小結(jié):
在啟動(dòng)引導(dǎo)類上面的mapper掃描注解 一定要修改為 通用mapper的掃描注解
14. Spring Boot整合-Junit
- 在springboot項(xiàng)目中如果要使用Junit進(jìn)行單元測試尘颓,則需要添加如下的依賴:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
- 在測試包下編寫測試類
在測試類上面必須要添加 @SpringBootTest 注解走触。
編寫測試類 springboot\src\test\java\com\nono\service\UserServiceTest.java
package com.nono.service;
import com.nono.pojo.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.Date;
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void queryById(){
User user = userService.queryById(1L);
System.out.println("user = " + user);
}
@Test
public void saveUser() {
User user = new User();
user.setUsername("test");
user.setName("test");
user.setPassword("123456");
user.setSex(1);
user.setAge(20);
user.setCreated(new Date());
userService.saveUser(user);
}
}
15. Spring Boot整合-redis
目標(biāo):在Spring Boot項(xiàng)目中使用Junit測試RedisTemplate的使用
分析:
- 添加啟動(dòng)器依賴;spring-boot-starter-data-redis
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 配置application.yml中修改redis的連接參數(shù)疤苹;(redis需要啟動(dòng))
spring:
redis:
host: localhost
port: 6379
- 編寫測試類應(yīng)用RedisTemplate操作redis中的5種數(shù)據(jù)類型(string/hash/list/set/sorted set)
編寫 src\test\java\com\nono\redis\RedisTest.java 測試代碼
package com.nono.redis;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import java.util.Set;
@RunWith(SpringRunner.class)
@SpringBootTest
public class RedisTest {
@Autowired
private RedisTemplate redisTemplate;
@Test
public void test(){
//string 字符串
//redisTemplate.opsForValue().set("str", "nono");
redisTemplate.boundValueOps("str").set("nono");
System.out.println("str = " + redisTemplate.opsForValue().get("str"));
//hash 散列
redisTemplate.boundHashOps("h_key").put("name", "Nono");
redisTemplate.boundHashOps("h_key").put("age", 13);
//獲取所有域
Set set = redisTemplate.boundHashOps("h_key").keys();
System.out.println(" hash散列的所有域:" + set);
//獲取所有值
List list = redisTemplate.boundHashOps("h_key").values();
System.out.println(" hash散列的所有域的值:" + list);
//list 列表
redisTemplate.boundListOps("l_key").leftPush("c");
redisTemplate.boundListOps("l_key").leftPush("b");
redisTemplate.boundListOps("l_key").leftPush("a");
//獲取全部元素
list = redisTemplate.boundListOps("l_key").range(0, -1);
System.out.println(" list列表中的所有元素:" + list);
// set 集合
redisTemplate.boundSetOps("s_key").add("a", "b", "c");
set = redisTemplate.boundSetOps("s_key").members();
System.out.println(" set集合中的所有元素:" + set);
// sorted set 有序集合
redisTemplate.boundZSetOps("z_key").add("a", 30);
redisTemplate.boundZSetOps("z_key").add("b", 20);
redisTemplate.boundZSetOps("z_key").add("c", 10);
set = redisTemplate.boundZSetOps("z_key").range(0, -1);
System.out.println(" zset有序集合中的所有元素:" + set);
}
}
16. Spring Boot項(xiàng)目部署
目標(biāo):將Spring Boot項(xiàng)目使用maven指令打成jar包并運(yùn)行測試
分析:
- 需要添加打包組件將項(xiàng)目中的資源互广、配置、依賴包打到一個(gè)jar包中卧土;可以使用maven的
package
惫皱; - 部署:java -jar 包名
- 添加項(xiàng)目的pom.xml插件;在pom.xml要顯式的加入插件spring-boot-maven-plugin,否則無法產(chǎn)生 jar 清單 文件尤莺,導(dǎo)致打出來的 jar 無法使用命令運(yùn)行;
<build>
<plugins>
<!-- 打jar包時(shí)如果不配置該插件旅敷,打出來的jar包沒有清單文件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
-
使用maven的命令package打包;
之后在項(xiàng)目下的 target 目錄中將有如下jar包:
運(yùn)行打出來的包;使用命令: java –jar 包全名 或者寫一個(gè) bat 文件,里面包含 java –jar 包全名;這樣就可以雙 擊啟動(dòng)應(yīng)用缝裁。
如執(zhí)行上述打出來的jar的命令為:
java -jar springboot-1.0-SNAPSHOT.jar
小結(jié):
-
添加打包組件
<build> <plugins> <!-- 打jar包時(shí)如果不配置該插件,打出來的jar包沒有清單文件 --> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build>
-
部署運(yùn)行
java -jar 包名
附錄—插件安裝
在應(yīng)用spring boot工程的時(shí)候;一般情況下都需要?jiǎng)?chuàng)建啟動(dòng)引導(dǎo)類Application.java和application.yml配置文件足绅,而 且內(nèi)容都是一樣的;為了便捷可以安裝一個(gè)IDEA的插件 JBLSpringBootAppGen 在項(xiàng)目上右擊之后可以自動(dòng)生成啟 動(dòng)引導(dǎo)類Application.java和application.yml配置文件捷绑。
安裝插件
應(yīng)用插件
在IDEA中任意一個(gè)maven項(xiàng)目或src目錄上 右擊,選擇 JBLSpringBootAppGen 即可氢妈。
在如下的界面中輸入 啟動(dòng)引導(dǎo)類的名稱并根據(jù)需要勾選是否要生成application.yml配置文件粹污。
點(diǎn)擊 OK 之后,在項(xiàng)目中將發(fā)現(xiàn)如下內(nèi)容: