Springboot

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)步驟:

  1. 創(chuàng)建工程井濒;


    image.png

看到這里很多同學(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)即可!

  1. 添加依賴(啟動(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>
  1. 創(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 如下:


    image.png
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);
    }
}
  1. 創(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}")

  1. 測試
    接下來,運(yùn)行main函數(shù)烫葬,查看控制臺:


    image.png

并且可以看到監(jiān)聽的端口信息:


image.png

1)監(jiān)聽的端口是8080
2)SpringMVC的項(xiàng)目路徑是:空

3)/hello 路徑已經(jīng)映射到了 HelloController 中的 hello() 方法
打開頁面訪問:http://localhost:8080/hello

image.png

小結(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代碼方式配置

image.png
image.png

目標(biāo):可以使用@Value獲取配置文件配置項(xiàng)并結(jié)合@Bean注冊組件到Spring

分析

需求:使用Java代碼配置數(shù)據(jù)庫連接池,并可以在處理器中注入并使用

步驟:

  1. 添加依賴厘灼;
    在 pom.xml 文件中添加Druid連接池依賴如下
<dependency>
          <groupId>com.alibaba</groupId>
          <artifactId>druid</artifactId>
          <version>1.1.10</version>
 </dependency>
  1. 創(chuàng)建數(shù)據(jù)庫夹纫;
  1. 創(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
  1. 創(chuàng)建配置類舰讹;
  2. 改造處理器類注入數(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;
    }
}

image.png

在 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)行并查看:


image.png

屬性注入成功了!

小結(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)步驟:

  1. 創(chuàng)建配置項(xiàng)類JdbcProperties類锄开,在該類名上面添加@ConfigurationProperties;
  2. 將jdbc.properties修改名稱為application.properties称诗;
  3. 將JdbcProperties對象注入到JdbcConfig萍悴;
  4. 測試

屬性文件的名稱有變化,默認(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)讀取的屬性文件名:


image.png

【注意】如果出現(xiàn)如下提示姑荷,項(xiàng)目也可以運(yùn)行;


image.png

如果要去掉上述的提示盒延,則可以在 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:


image.png

3)測試結(jié)果;與前面的測試一樣的鼠冕。
大家會覺得這種方式似乎更麻煩了添寺,事實(shí)上這種方式有更強(qiáng)大的功能,也是Spring Boot推薦的注入方式懈费。與@Value 對比關(guān)系:

image.png

優(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配置文件的特征:

  1. 樹狀層級結(jié)構(gòu)展示配置項(xiàng)中姜;
  2. 配置項(xiàng)之間如果有關(guān)系的話需要分行空兩格消玄;
  3. 配置項(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ù)
1560091228494.png

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注解則才安裝插件。


image.png

需要在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等方法的編寫。

    1. 在IDEA中安裝lombok插件承冰;
    2. 添加lombok對應(yīng)的依賴到項(xiàng)目pom.xml文件华弓;
    3. 改造實(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)查找路徑:

image.png

默認(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 如下:


image.png

image.png

9.Spring Boot整合-SpringMVC攔截器

目標(biāo):可以在Spring Boot項(xiàng)目中配置自定義SpringMVC攔截器

攔截器不是一個(gè)普通屬性,而是一個(gè)類谭企,所以就要用到j(luò)ava配置方式了廓译。在SpringBoot官方文檔中有這么一段說明:

image.png

分析

  1. 編寫攔截器(實(shí)現(xiàn)HandlerInterceptor);
  2. 編寫配置類實(shí)現(xiàn) WebMvcConfigurer债查,在該類中添加各種組件非区;
  3. 測試

總結(jié):通過實(shí)現(xiàn) WebMvcConfigurer 并添加 @Configuration 注解來實(shí)現(xiàn)自定義部分SpringMvc配置。

  1. 創(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方法");
    }
}

  1. 定義配置類 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)如下:


image.png
image.png

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è)連接池:


image.png

HikariCP應(yīng)該是目前速度最快的連接池了砾莱,我們看看它與c3p0的對比:

image.png

因此瑞筐,我們只需要指定連接池參數(shù)即可;打開 application.yml 添加修改配置如下:


image.png

【注意】
把 JdbcConfig 類中的druid的配置刪除或注釋;

image.png

在配置完hikari數(shù)據(jù)庫連接池后的 application.yml 文件如下:


image.png

啟動(dòng)項(xiàng)目,訪問 http://localhost/hello ;查看后臺輸出,一樣可以在HelloController中獲取到datasource聚假。

image.png

目標(biāo):配置Spring Boot自帶默認(rèn)的hikari數(shù)據(jù)庫連接池和使用@Transactional注解進(jìn)行事務(wù)配置

分析

  • 事務(wù)配置

    1. 添加事務(wù)相關(guān)的啟動(dòng)器依賴块蚌,mysql相關(guān)依賴;
    2. 編寫業(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

  1. 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>
  1. 配置 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
  1. 配置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)

分析

  1. 添加啟動(dòng)器依賴共螺;
  2. 配置Mybatis:實(shí)體類別名包该肴,日志,映射文件等藐不;
  3. 配置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

  1. 通用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)器 的依賴。

  1. 編寫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> {

}
  1. 把啟動(dòng)類上的@MapperScan注解修改為通用mapper中自帶的:


    image.png
  1. 在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ā)效率刁憋。

  1. 添加啟動(dòng)器依賴;
  2. 改造UserMapper繼承Mapper<User>木蹬;
  3. 修改啟動(dòng)引導(dǎo)類Application中的Mapper掃描注解至耻;
  4. 修改User實(shí)體類添加jpa注解;
  5. 改造UserService實(shí)現(xiàn)業(yè)務(wù)功能;

小結(jié)

在啟動(dòng)引導(dǎo)類上面的mapper掃描注解 一定要修改為 通用mapper的掃描注解

14. Spring Boot整合-Junit

  1. 在springboot項(xiàng)目中如果要使用Junit進(jìn)行單元測試尘颓,則需要添加如下的依賴:
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>

  1. 在測試包下編寫測試類
    在測試類上面必須要添加 @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的使用

分析

  1. 添加啟動(dòng)器依賴;spring-boot-starter-data-redis
<dependency>
     <groupId>org.springframework.boot</groupId>
     <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  1. 配置application.yml中修改redis的連接參數(shù)疤苹;(redis需要啟動(dòng))
spring:
  redis:
    host: localhost
    port: 6379
  1. 編寫測試類應(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)行測試

分析

  1. 需要添加打包組件將項(xiàng)目中的資源互广、配置、依賴包打到一個(gè)jar包中卧土;可以使用maven的package惫皱;
  2. 部署:java -jar 包名
  1. 添加項(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>
  1. 使用maven的命令package打包;


    image.png

之后在項(xiàng)目下的 target 目錄中將有如下jar包:


image.png
image.png

運(yùn)行打出來的包;使用命令: java –jar 包全名 或者寫一個(gè) bat 文件,里面包含 java –jar 包全名;這樣就可以雙 擊啟動(dòng)應(yīng)用缝裁。
如執(zhí)行上述打出來的jar的命令為:

java -jar springboot-1.0-SNAPSHOT.jar
image.png

小結(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配置文件捷绑。

安裝插件

image.png

應(yīng)用插件

在IDEA中任意一個(gè)maven項(xiàng)目或src目錄上 右擊,選擇 JBLSpringBootAppGen 即可氢妈。


image.png

在如下的界面中輸入 啟動(dòng)引導(dǎo)類的名稱并根據(jù)需要勾選是否要生成application.yml配置文件粹污。

image.png

點(diǎn)擊 OK 之后,在項(xiàng)目中將發(fā)現(xiàn)如下內(nèi)容:


image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末首量,一起剝皮案震驚了整個(gè)濱河市壮吩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌加缘,老刑警劉巖鸭叙,帶你破解...
    沈念sama閱讀 212,884評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異拣宏,居然都是意外死亡沈贝,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,755評論 3 385
  • 文/潘曉璐 我一進(jìn)店門勋乾,熙熙樓的掌柜王于貴愁眉苦臉地迎上來宋下,“玉大人,你說我怎么就攤上這事辑莫⊙纾” “怎么了?”我有些...
    開封第一講書人閱讀 158,369評論 0 348
  • 文/不壞的土叔 我叫張陵各吨,是天一觀的道長枝笨。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么伺帘? 我笑而不...
    開封第一講書人閱讀 56,799評論 1 285
  • 正文 為了忘掉前任昭躺,我火速辦了婚禮,結(jié)果婚禮上伪嫁,老公的妹妹穿的比我還像新娘领炫。我一直安慰自己,他們只是感情好张咳,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,910評論 6 386
  • 文/花漫 我一把揭開白布帝洪。 她就那樣靜靜地躺著,像睡著了一般脚猾。 火紅的嫁衣襯著肌膚如雪葱峡。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 50,096評論 1 291
  • 那天龙助,我揣著相機(jī)與錄音砰奕,去河邊找鬼。 笑死提鸟,一個(gè)胖子當(dāng)著我的面吹牛军援,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播称勋,決...
    沈念sama閱讀 39,159評論 3 411
  • 文/蒼蘭香墨 我猛地睜開眼胸哥,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了赡鲜?” 一聲冷哼從身側(cè)響起空厌,我...
    開封第一講書人閱讀 37,917評論 0 268
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎银酬,沒想到半個(gè)月后嘲更,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,360評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡揩瞪,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,673評論 2 327
  • 正文 我和宋清朗相戀三年哮内,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片壮韭。...
    茶點(diǎn)故事閱讀 38,814評論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡北发,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出喷屋,到底是詐尸還是另有隱情琳拨,我是刑警寧澤,帶...
    沈念sama閱讀 34,509評論 4 334
  • 正文 年R本政府宣布屯曹,位于F島的核電站狱庇,受9級特大地震影響扭勉,放射性物質(zhì)發(fā)生泄漏记某。R本人自食惡果不足惜衅鹿,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,156評論 3 317
  • 文/蒙蒙 一愕够、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧浪讳,春花似錦缰盏、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,882評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至透揣,卻和暖如春济炎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背辐真。 一陣腳步聲響...
    開封第一講書人閱讀 32,123評論 1 267
  • 我被黑心中介騙來泰國打工须尚, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人侍咱。 一個(gè)月前我還...
    沈念sama閱讀 46,641評論 2 362
  • 正文 我出身青樓耐床,卻偏偏與公主長得像,于是被迫代替她去往敵國和親放坏。 傳聞我的和親對象是個(gè)殘疾皇子咙咽,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,728評論 2 351