SpringBoot教程

一、SpringBoot簡介

1.1  原有Spring優缺點分析

1.1.1 Spring的優點分析

 1.1.2 Spring的缺點分析

1.2 SpringBoot的概述

1.2.1 SpringBoot解決上述Spring的缺點

1.2.2 SpringBoot的特點

1.2.3 SpringBoot的核心功能

 二、SpringBoot快速入門

 2.1 代碼實現

2.1.1 創建Maven工程

2.1.2 添加SpringBoot的起步依賴

2.1.3 編寫SpringBoot引導類

2.1.4 編寫Controller

 2.1.5 測試

2.2 快速入門解析

 2.2.2 SpringBoot代碼解析

 2.2.3 SpringBoot工程熱部署

2.2.4 使用idea快速創建SpringBoot項目

三、SpringBoot原理分析

3.1 起步依賴原理分析

3.1.1 分析spring-boot-starter-parent

3.1.2 分析spring-boot-starter-web

3.2 自動配置原理解析

四、SpringBoot的配置文件

4.1 SpringBoot配置文件類型

4.1.1 SpringBoot配置文件類型和作用

 4.1.2 application.yml配置文件

4.1.3 SpringBoot配置信息的查詢

4.2 配置文件與配置類的屬性映射方式

 4.2.1 使用註解@Value映射

4.2.2 使用註解@ConfigurationProperties映射

 五、SpringBoot與整合其他技術

5.1 SpringBoot整合Mybatis

5.1.1 添加Mybatis的起步依賴

5.1.2 添加數據庫驅動座標

5.1.3 添加數據庫連接信息

5.1.4 創建user表

5.1.5 創建實體Bean

5.1.6 編寫Mapper

5.1.7 配置Mapper映射文件

 5.1.8 在application.properties中添加mybatis的信息

5.1.9 編寫測試Controller

 5.1.10 測試

 5.2 SpringBoot整合Junit

 5.2.1 添加Junit的起步依賴

5.2.2 編寫測試類

5.2.3 控制檯打印信息

5.3 SpringBoot整合Spring Data JPA

5.3.1 添加Spring Data JPA的起步依賴

5.3.3 在application.properties中配置數據庫和jpa的相關屬性

 5.3.4 創建實體配置實體

5.3.5 編寫UserRepository

5.3.6 編寫測試類

5.3.7 控制檯打印信息

5.4 SpringBoot整合Redis

 5.4.1 添加redis的起步依賴

5.4.2 配置redis的連接信息

5.4.3 注入RedisTemplate測試redis操作


一、SpringBoot簡介

1.1  原有Spring優缺點分析

1.1.1 Spring的優點分析

Spring是Java企業版(Java Enterprise Edition,JEE,也稱J2EE)的輕量級代替品。無需開發重量級的Enterprise JavaBean(EJB),Spring爲企業級Java開發提供了一種相對簡單的方法,通過依賴注入和麪向切面編程,用簡單的Java對象(Plain Old Java Object,POJO)實現了EJB的功能。

 1.1.2 Spring的缺點分析

雖然Spring的組件代碼是輕量級的,但它的配置卻是重量級的。一開始,Spring用XML配置,而且是很多XML配置。Spring 2.5引入了基於註解的組件掃描,這消除了大量針對應用程序自身組件的顯式XML配置。Spring 3.0引入了基於Java的配置,這是一種類型安全的可重構配置方式,可以代替XML。

所有這些配置都代表了開發時的損耗。因爲在思考Spring特性配置和解決業務問題之間需要進行思維切換,所以編寫配置擠佔了編寫應用程序邏輯的時間。和所有框架一樣,Spring實用,但與此同時它要求的回報也不少。

除此之外,項目的依賴管理也是一件耗時耗力的事情。在環境搭建時,需要分析要導入哪些庫的座標,而且還需要分析導入與之有依賴關係的其他庫的座標,一旦選錯了依賴的版本,隨之而來的不兼容問題就會嚴重阻礙項目的開發進度。

1.2 SpringBoot的概述

1.2.1 SpringBoot解決上述Spring的缺點

SpringBoot對上述Spring的缺點進行的改善和優化,基於約定優於配置的思想,可以讓開發人員不必在配置與邏輯業務之間進行思維的切換,全身心的投入到邏輯業務的代碼編寫中,從而大大提高了開發的效率,一定程度上縮短了項目週期。

1.2.2 SpringBoot的特點

  • 爲基於Spring的開發提供更快的入門體驗
  • 開箱即用,沒有代碼生成,也無需XML配置。同時也可以修改默認值來滿足特定的需求
  • 提供了一些大型項目中常見的非功能性特性,如嵌入式服務器、安全、指標,健康檢測、外部配置等
  • SpringBoot不是對Spring功能上的增強,而是提供了一種快速使用Spring的方式

1.2.3 SpringBoot的核心功能

  • 起步依賴

  起步依賴本質上是一個Maven項目對象模型(Project Object Model,POM),定義了對其他庫的傳遞依賴,這些東西加在一起即支持某項功能。

  簡單的說,起步依賴就是將具備某種功能的座標打包到一起,並提供一些默認的功能。

  • 自動配置

  Spring Boot的自動配置是一個運行時(更準確地說,是應用程序啓動時)的過程,考慮了衆多因素,才決定Spring配置應該用哪個,不該用哪個。該過程是Spring自動完成的。

 

 二、SpringBoot快速入門

 2.1 代碼實現

2.1.1 創建Maven工程

使用idea工具創建一個maven工程,該工程爲普通的java工程即可

 

2.1.2 添加SpringBoot的起步依賴

SpringBoot要求,項目要繼承SpringBoot的起步依賴spring-boot-starter-parent

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.RELEASE</version>
</parent>

SpringBoot要集成SpringMVC進行Controller的開發,所以項目要導入web的啓動依賴

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
</dependencies>

 

2.1.3 編寫SpringBoot引導類

要通過SpringBoot提供的引導類起步SpringBoot纔可以進行訪問,注意該類不能從組件的默認包啓動,所以需要建立一個包,然後將引導類放入其中。

package com.neuq;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @Description TODO
 * @Author WS
 * @Date 2019/6/25 18:05
 * @Version 1.0
 **/
@SpringBootApplication
public class AppRun {
    public static void main(String[] args) {
        SpringApplication.run(AppRun.class,args);
    }
}

 

2.1.4 編寫Controller

在引導類MySpringBootApplication同級包或者子級包中創建LoginController

package com.neuq.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

/**
 * @Description TODO
 * @Author WS
 * @Date 2019/6/25 18:08
 * @Version 1.0
 **/
@Controller
public class LoginController {
    @RequestMapping("/login")
    @ResponseBody
    public String login(){
        return "login ok!";
    }
}

 

 2.1.5 測試

執行SpringBoot起步類的主方法,控制檯打印日誌如下:


  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.0.1.RELEASE)

2019-06-25 20:29:13.087  INFO 7760 --- [           main] com.neuq.AppRun                          : Starting AppRun on DESKTOP-EJQVC89 with PID 7760 (F:\IDEAworkplace\SpringBootTest\target\classes started by shun in F:\IDEAworkplace\SpringBootTest)
2019-06-25 20:29:13.092  INFO 7760 --- [           main] com.neuq.AppRun                          : No active profile set, falling back to default profiles: default
2019-06-25 20:29:13.305  INFO 7760 --- [           main] ConfigServletWebServerApplicationContext : Refreshing org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@448ff1a8: startup date [Tue Jun 25 20:29:13 CST 2019]; root of context hierarchy
2019-06-25 20:29:17.691  INFO 7760 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port(s): 8080 (http)
2019-06-25 20:29:17.741  INFO 7760 --- [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2019-06-25 20:29:17.741  INFO 7760 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/8.5.29
2019-06-25 20:29:17.765  INFO 7760 --- [ost-startStop-1] o.a.catalina.core.AprLifecycleListener   : The APR based Apache Tomcat Native library which allows optimal performance in production environments was not found on the java.library.path: [F:\jdk1.8\bin;C:\WINDOWS\Sun\Java\bin;C:\WINDOWS\system32;C:\WINDOWS;C:\ProgramData\Oracle\Java\javapath;F:\jdk1.8\bin;C:\Program Files (x86)\Intel\iCLS Client\;C:\Program Files\Intel\iCLS Client\;C:\Windows\system32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\v1.0\;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files\Intel\Intel(R) Management Engine Components\DAL;C:\Program Files (x86)\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files\Intel\Intel(R) Management Engine Components\IPT;C:\Program Files (x86)\NVIDIA Corporation\PhysX\Common;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;D:\Mysql\bin;C:\WINDOWS\System32\OpenSSH\;F:\Git\cmd;F:\maven\soft\apache-maven-3.5.4\bin;D:\MiKTeX 2.9\miktex\bin\x64;F:\Anaconda3\Scripts;F:\pandoc-2.5-windows-x86_64;F:\hadoop\hadoop-2.8.1-windows\hadoop-2.8.1\bin;F:\scala\scala-2.11.8\bin;F:\Anaconda3\Scripts\;F:\Anaconda3\;C:\Users\順\AppData\Local\Microsoft\WindowsApps;C:\Users\順\AppData\Local\GitHubDesktop\bin;C:\Users\順\AppData\Local\Microsoft\WindowsApps;f:\JetBrains\PyCharm 183.2153.9\bin;;D:\MiKTeX 2.9\miktex\bin\x64\;;.]
2019-06-25 20:29:18.246  INFO 7760 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-06-25 20:29:18.247  INFO 7760 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 4947 ms
2019-06-25 20:29:18.532  INFO 7760 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean  : Servlet dispatcherServlet mapped to [/]
2019-06-25 20:29:18.543  INFO 7760 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'characterEncodingFilter' to: [/*]
2019-06-25 20:29:18.543  INFO 7760 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2019-06-25 20:29:18.544  INFO 7760 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2019-06-25 20:29:18.544  INFO 7760 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean   : Mapping filter: 'requestContextFilter' to: [/*]
2019-06-25 20:29:18.791  INFO 7760 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-06-25 20:29:19.162  INFO 7760 --- [           main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext@448ff1a8: startup date [Tue Jun 25 20:29:13 CST 2019]; root of context hierarchy
2019-06-25 20:29:19.306  INFO 7760 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/login]}" onto public java.lang.String com.neuq.controller.LoginController.login()
2019-06-25 20:29:19.315  INFO 7760 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2019-06-25 20:29:19.316  INFO 7760 --- [           main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.servlet.error.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2019-06-25 20:29:19.357  INFO 7760 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-06-25 20:29:19.358  INFO 7760 --- [           main] o.s.w.s.handler.SimpleUrlHandlerMapping  : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2019-06-25 20:29:19.625  INFO 7760 --- [           main] o.s.j.e.a.AnnotationMBeanExporter        : Registering beans for JMX exposure on startup
2019-06-25 20:29:19.686  INFO 7760 --- [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port(s): 8080 (http) with context path ''
2019-06-25 20:29:19.693  INFO 7760 --- [           main] com.neuq.AppRun                          : Started AppRun in 7.275 seconds (JVM running for 8.729)

 

通過日誌發現,Tomcat started on port(s): 8080 (http) with context path ''

tomcat已經起步,端口監聽8080,web應用的虛擬工程名稱爲空

打開瀏覽器訪問url地址爲:http://localhost:8080/login

2.2 快速入門解析

 2.2.2 SpringBoot代碼解析

  • @SpringBootApplication:標註SpringBoot的啓動類,該註解具備多種功能(後面詳細剖析)
  • SpringApplication.run(MySpringBootApplication.class) 代表運行SpringBoot的啓動類,參數爲SpringBoot啓動類的字節碼對象

 2.2.3 SpringBoot工程熱部署

我們在開發中反覆修改類、頁面等資源,每次修改後都是需要重新啓動才生效,這樣每次啓動都很麻煩,浪費了大量的時間,我們可以在修改代碼後不重啓就能生效,在 pom.xml 中添加如下配置就可以實現這樣的功能,我們稱之爲熱部署。

<!--熱部署配置-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-devtools</artifactId>
</dependency>

注意:IDEA進行SpringBoot熱部署失敗原因

出現這種情況,並不是熱部署配置問題,其根本原因是因爲Intellij IEDA默認情況下不會自動編譯,需要對IDEA進行自動編譯的設置,如下:

然後 Shift+Ctrl+Alt+/,選擇Registry

2.2.4 使用idea快速創建SpringBoot項目

 

 

通過idea快速創建的SpringBoot項目的pom.xml中已經導入了我們選擇的web的起步依賴的座標

<?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>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

 

可以使用快速入門的方式創建Controller進行訪問,此處不再贅述

 

三、SpringBoot原理分析

3.1 起步依賴原理分析

3.1.1 分析spring-boot-starter-parent

按住Ctrl點擊pom.xml中的spring-boot-starter-parent,跳轉到了spring-boot-starter-parent的pom.xml,xml配置如下(只摘抄了部分重點配置):

<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>2.0.1.RELEASE</version>
  <relativePath>../../spring-boot-dependencies</relativePath>
</parent>

按住Ctrl點擊pom.xml中的spring-boot-starter-dependencies,跳轉到了spring-boot-starter-dependencies的pom.xml,xml配置如下(只摘抄了部分重點配置):

<properties>
      <activemq.version>5.15.3</activemq.version>
      <antlr2.version>2.7.7</antlr2.version>
      <appengine-sdk.version>1.9.63</appengine-sdk.version>
      <artemis.version>2.4.0</artemis.version>
      <aspectj.version>1.8.13</aspectj.version>
      <assertj.version>3.9.1</assertj.version>
      <atomikos.version>4.0.6</atomikos.version>
      <bitronix.version>2.1.4</bitronix.version>
      <build-helper-maven-plugin.version>3.0.0</build-helper-maven-plugin.version>
      <byte-buddy.version>1.7.11</byte-buddy.version>
      ... ... ...
</properties>
<dependencyManagement>
      <dependencies>
          <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot</artifactId>
            <version>2.0.1.RELEASE</version>
          </dependency>
          <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-test</artifactId>
            <version>2.0.1.RELEASE</version>
          </dependency>
          ... ... ...
    </dependencies>
</dependencyManagement>
<build>
      <pluginManagement>
        <plugins>
              <plugin>
                <groupId>org.jetbrains.kotlin</groupId>
                <artifactId>kotlin-maven-plugin</artifactId>
                <version>${kotlin.version}</version>
              </plugin>
              <plugin>
                <groupId>org.jooq</groupId>
                <artifactId>jooq-codegen-maven</artifactId>
                <version>${jooq.version}</version>
              </plugin>
              <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <version>2.0.1.RELEASE</version>
              </plugin>
              ... ... ...
        </plugins>
      </pluginManagement>
</build>

從上面的spring-boot-starter-dependencies的pom.xml中我們可以發現,一部分座標的版本、依賴管理、插件管理已經定義好,所以我們的SpringBoot工程繼承spring-boot-starter-parent後已經具備版本鎖定等配置了。所以起步依賴的作用就是進行依賴的傳遞。

3.1.2 分析spring-boot-starter-web

按住Ctrl點擊pom.xml中的spring-boot-starter-web,跳轉到了spring-boot-starter-web的pom.xml,xml配置如下(只摘抄了部分重點配置):

<?xml version="1.0" encoding="UTF-8"?>
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
      <modelVersion>4.0.0</modelVersion>
      <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starters</artifactId>
        <version>2.0.1.RELEASE</version>
      </parent>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      <version>2.0.1.RELEASE</version>
      <name>Spring Boot Web Starter</name>
 
      <dependencies>
        <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter</artifactId>
              <version>2.0.1.RELEASE</version>
              <scope>compile</scope>
        </dependency>
        <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-json</artifactId>
              <version>2.0.1.RELEASE</version>
              <scope>compile</scope>
        </dependency>
        <dependency>
              <groupId>org.springframework.boot</groupId>
              <artifactId>spring-boot-starter-tomcat</artifactId>
              <version>2.0.1.RELEASE</version>
              <scope>compile</scope>
        </dependency>
        <dependency>
              <groupId>org.hibernate.validator</groupId>
              <artifactId>hibernate-validator</artifactId>
              <version>6.0.9.Final</version>
              <scope>compile</scope>
        </dependency>
        <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-web</artifactId>
              <version>5.0.5.RELEASE</version>
              <scope>compile</scope>
        </dependency>
        <dependency>
              <groupId>org.springframework</groupId>
              <artifactId>spring-webmvc</artifactId>
              <version>5.0.5.RELEASE</version>
              <scope>compile</scope>
        </dependency>
      </dependencies>
</project>

 

從上面的spring-boot-starter-web的pom.xml中我們可以發現,spring-boot-starter-web就是將web開發要使用的spring-web、spring-webmvc等座標進行了“打包”,這樣我們的工程只要引入spring-boot-starter-web起步依賴的座標就可以進行web開發了,同樣體現了依賴傳遞的作用。

 

3.2 自動配置原理解析

按住Ctrl點擊查看啓動類上的註解@SpringBootApplication

註解@SpringBootApplication的源碼

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = {
        @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

    /**
     * Exclude specific auto-configuration classes such that they will never be applied.
     * @return the classes to exclude
     */
    @AliasFor(annotation = EnableAutoConfiguration.class)
    Class<?>[] exclude() default {};

    ... ... ...

}

其中,

@SpringBootConfiguration:等同與@Configuration,既標註該類是Spring的一個配置類

@EnableAutoConfiguration:SpringBoot自動配置功能開啓

按住Ctrl點擊查看註解@EnableAutoConfiguration

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
    ... ... ...
}

其中,@Import(AutoConfigurationImportSelector.class) 導入了AutoConfigurationImportSelector類

按住Ctrl點擊查看AutoConfigurationImportSelector源碼

public String[] selectImports(AnnotationMetadata annotationMetadata) {
        ... ... ...
        List<String> configurations = getCandidateConfigurations(annotationMetadata,
                                                                   attributes);
        configurations = removeDuplicates(configurations);
        Set<String> exclusions = getExclusions(annotationMetadata, attributes);
        checkExcludedClasses(configurations, exclusions);
        configurations.removeAll(exclusions);
        configurations = filter(configurations, autoConfigurationMetadata);
        fireAutoConfigurationImportEvents(configurations, exclusions);
        return StringUtils.toStringArray(configurations);
}


protected List<String> getCandidateConfigurations(AnnotationMetadata metadata,
            AnnotationAttributes attributes) {
        List<String> configurations = SpringFactoriesLoader.loadFactoryNames(
                getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader());
        
        return configurations;
}

其中,SpringFactoriesLoader.loadFactoryNames 方法的作用就是從META-INF/spring.factories文件中讀取指定類對應的類名稱列表

spring.factories 文件中有關自動配置的配置信息如下:

org.springframework.boot.autoconfigure.web.reactive.function.client.WebClientAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.ServletWebServerFactoryAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.error.ErrorMvcAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.HttpEncodingAutoConfiguration,\
org.springframework.boot.autoconfigure.web.servlet.MultipartAutoConfiguration,\

 

上面配置文件存在大量的以Configuration爲結尾的類名稱,這些類就是存有自動配置信息的類,而SpringApplication在獲取這些類名後再加載

我們以ServletWebServerFactoryAutoConfiguration爲例來分析源碼:

@Configuration
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@ConditionalOnClass(ServletRequest.class)
@ConditionalOnWebApplication(type = Type.SERVLET)
@EnableConfigurationProperties(ServerProperties.class)
@Import({ ServletWebServerFactoryAutoConfiguration.BeanPostProcessorsRegistrar.class,
        ServletWebServerFactoryConfiguration.EmbeddedTomcat.class,
        ServletWebServerFactoryConfiguration.EmbeddedJetty.class,
        ServletWebServerFactoryConfiguration.EmbeddedUndertow.class })
public class ServletWebServerFactoryAutoConfiguration {
    ... ... ...
}

其中,

@EnableConfigurationProperties(ServerProperties.class) 代表加載ServerProperties服務器配置屬性類

進入ServerProperties.class源碼如下:

@ConfigurationProperties(prefix = "server", ignoreUnknownFields = true)
public class ServerProperties {

    /**
     * Server HTTP port.
     */
    private Integer port;

    /**
     * Network address to which the server should bind.
     */
    private InetAddress address;
 
      ... ... ...
 
}

其中,

prefix = "server" 表示SpringBoot配置文件中的前綴,SpringBoot會將配置文件中以server開始的屬性映射到該類的字段中。映射關係如下:

四、SpringBoot的配置文件

4.1 SpringBoot配置文件類型

4.1.1 SpringBoot配置文件類型和作用

SpringBoot是基於約定的,所以很多配置都有默認值,但如果想使用自己的配置替換默認配置的話,就可以使用application.properties或者application.yml(application.yaml)進行配置。

SpringBoot默認會從Resources目錄下加載application.properties或application.yml(application.yaml)文件

其中,application.properties文件是鍵值對類型的文件,之前一直在使用,所以此處不在對properties文件的格式進行闡述。除了properties文件外,SpringBoot還可以使用yml文件進行配置,下面對yml文件進行講解。

 4.1.2 application.yml配置文件

 4.1.2.1 yml配置文件簡介

YML文件格式是YAML (YAML Aint Markup Language)編寫的文件格式,YAML是一種直觀的能夠被電腦識別的的數據數據序列化格式,並且容易被人類閱讀,容易和腳本語言交互的,可以被支持YAML庫的不同的編程語言程序導入,比如: C/C++, Ruby, Python, Java, Perl, C#, PHP等。YML文件是以數據爲核心的,比傳統的xml方式更加簡潔。

YML文件的擴展名可以使用.yml或者.yaml。

4.1.2.2 yml配置文件的語法

4.1.2.2.1 配置普通數據

  • 語法: key: value
  • 示例代碼:
 name: haohao
  •  注意:value之前有一個空格

4.1.2.2.2 配置對象數據

  • 語法:

  ​    key:

  ​        key1: value1

  ​        key2: value2

  ​    或者:

  ​    key: {key1: value1,key2: value2}

  •  示例代碼:
 person:
    name: haohao
    age: 31
    addr: beijing

  或者

 

 person: {name: haohao,age: 31,addr: beijing}

 

  •  注意:key1前面的空格個數不限定,在yml語法中,相同縮進代表同一個級別

4.1.2.2.2 配置Map數據

同上面的對象寫法

 4.1.2.2.3 配置數組(List、Set)數據

  • 語法:

  ​  

 key:

  ​  - value1

  ​  - value2

  或者:

  ​    

key: [value1,value2]
  • 示例代碼:


 

city:
    - beijing
    - tianjin
    - shanghai
    - chongqing


  或者

  city: [beijing,tianjin,shanghai,chongqing]

  集合中的元素是對象形式
 

student:
    - name: zhangsan
      age: 18
      score: 100
    - name: lisi
      age: 28
      score: 88
    - name: wangwu
      age: 38
      score: 90

 注意:value1與之間的 - 之間存在一個空格

4.1.3 SpringBoot配置信息的查詢

上面提及過,SpringBoot的配置文件,主要的目的就是對配置信息進行修改的,但在配置時的key從哪裏去查詢呢?我們可以查閱SpringBoot的官方文檔

文檔URL:

https://docs.spring.io/spring-boot/docs/2.0.1.RELEASE/reference/htmlsingle/#common-application-properties

常用的配置摘抄如下:

# QUARTZ SCHEDULER (QuartzProperties)
spring.quartz.jdbc.initialize-schema=embedded # Database schema initialization mode.
spring.quartz.jdbc.schema=classpath:org/quartz/impl/jdbcjobstore/tables_@@platform@@.sql # Path to the SQL file to use to initialize the database schema.
spring.quartz.job-store-type=memory # Quartz job store type.
spring.quartz.properties.*= # Additional Quartz Scheduler properties.

# ----------------------------------------
# WEB PROPERTIES
# ----------------------------------------

# EMBEDDED SERVER CONFIGURATION (ServerProperties)
server.port=8080 # Server HTTP port.
server.servlet.context-path= # Context path of the application.
server.servlet.path=/ # Path of the main dispatcher servlet.

# HTTP encoding (HttpEncodingProperties)
spring.http.encoding.charset=UTF-8 # Charset of HTTP requests and responses. Added to the "Content-Type" header if not set explicitly.

# JACKSON (JacksonProperties)
spring.jackson.date-format= # Date format string or a fully-qualified date format class name. For instance, `yyyy-MM-dd HH:mm:ss`.

# SPRING MVC (WebMvcProperties)
spring.mvc.servlet.load-on-startup=-1 # Load on startup priority of the dispatcher servlet.
spring.mvc.static-path-pattern=/** # Path pattern used for static resources.
spring.mvc.view.prefix= # Spring MVC view prefix.
spring.mvc.view.suffix= # Spring MVC view suffix.

# DATASOURCE (DataSourceAutoConfiguration & DataSourceProperties)
spring.datasource.driver-class-name= # Fully qualified name of the JDBC driver. Auto-detected based on the URL by default.
spring.datasource.password= # Login password of the database.
spring.datasource.url= # JDBC URL of the database.
spring.datasource.username= # Login username of the database.

# JEST (Elasticsearch HTTP client) (JestProperties)
spring.elasticsearch.jest.password= # Login password.
spring.elasticsearch.jest.proxy.host= # Proxy host the HTTP client should use.
spring.elasticsearch.jest.proxy.port= # Proxy port the HTTP client should use.
spring.elasticsearch.jest.read-timeout=3s # Read timeout.
spring.elasticsearch.jest.username= # Login username.

我們可以通過配置application.poperties 或者 application.yml 來修改SpringBoot的默認配置

例如:

application.properties文件

server.port=8888
server.servlet.context-path=demo

application.yml文件

server:
  port: 8888
  servlet:
    context-path: /demo

 

4.2 配置文件與配置類的屬性映射方式

 4.2.1 使用註解@Value映射

我們可以通過@Value註解將配置文件中的值映射到一個Spring管理的Bean的字段上

例如:

application.properties配置如下:

person:
  name: zhangsan
  age: 18

或者,application.yml配置如下:

person:
  name: zhangsan
  age: 18

實體Bean代碼如下:
 

@Controller
public class QuickStartController {

    @Value("${person.name}")
    private String name;
    @Value("${person.age}")
    private Integer age;


    @RequestMapping("/quick")
    @ResponseBody
    public String quick(){
        return "springboot 訪問成功! name="+name+",age="+age;
    }

}

瀏覽器訪問地址:http://localhost:8080/quick 結果如下:

 

4.2.2 使用註解@ConfigurationProperties映射

通過註解@ConfigurationProperties(prefix="配置文件中的key的前綴")可以將配置文件中的配置自動與實體進行映射

application.properties配置如下:

person:
  name: zhangsan
  age: 18

或者,application.yml配置如下:

person:
  name: zhangsan
  age: 18

實體Bean代碼如下:
 

@Controller
@ConfigurationProperties(prefix = "person")
public class QuickStartController {

    private String name;
    private Integer age;

    @RequestMapping("/quick")
    @ResponseBody
    public String quick(){
        return "springboot 訪問成功! name="+name+",age="+age;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

瀏覽器訪問地址:http://localhost:8080/quick 結果如下:

注意:使用@ConfigurationProperties方式可以進行配置文件與實體字段的自動映射,但需要字段必須提供set方法纔可以,而使用@Value註解修飾的字段不需要提供set方法

 

 五、SpringBoot與整合其他技術

5.1 SpringBoot整合Mybatis

5.1.1 添加Mybatis的起步依賴

<!--mybatis起步依賴-->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.1.1</version>
</dependency>

5.1.2 添加數據庫驅動座標

<!-- MySQL連接驅動 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

5.1.3 添加數據庫連接信息

在application.properties中添加數據量的連接信息

#DB Configuration:
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root

5.1.4 創建user表

在test數據庫中創建user表

- ----------------------------
-- Table structure for `user`
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(50) DEFAULT NULL,
  `password` varchar(50) DEFAULT NULL,
  `name` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'zhangsan', '123', '張三');
INSERT INTO `user` VALUES ('2', 'lisi', '123', '李四');

5.1.5 創建實體Bean

public class User {
    // 主鍵
    private Long id;
    // 用戶名
    private String username;
    // 密碼
    private String password;
    // 姓名
    private String name;
 
    //此處省略getter和setter方法 .. ..
    
}

5.1.6 編寫Mapper

@Mapper
public interface UserMapper {
    public List<User> queryUserList();
}

注意:@Mapper標記該類是一個mybatis的mapper接口,可以被spring boot自動掃描到spring上下文中

5.1.7 配置Mapper映射文件

在src\main\resources\mapper路徑下加入UserMapper.xml配置文件"

<?xml version="1.0" encoding="utf-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.itheima.mapper.UserMapper">
    <select id="queryUserList" resultType="user">
        select * from user
    </select>
</mapper>

 5.1.8 在application.properties中添加mybatis的信息

#spring集成Mybatis環境
#pojo別名掃描包
mybatis.type-aliases-package=com.itheima.domain
#加載Mybatis映射文件
mybatis.mapper-locations=classpath:mapper/*Mapper.xml

5.1.9 編寫測試Controller

@Controller
public class MapperController {

    @Autowired
    private UserMapper userMapper;

    @RequestMapping("/queryUser")
    @ResponseBody
    public List<User> queryUser(){
        List<User> users = userMapper.queryUserList();
        return users;
    }

}

 5.1.10 測試

 5.2 SpringBoot整合Junit

 5.2.1 添加Junit的起步依賴

<!--測試的起步依賴-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
</dependency>

5.2.2 編寫測試類

package com.neuq.test;

import com.neuq.MySpringBootApplication;
import com.neuq.domain.User;
import com.neuq.mapper.UserMapper;
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.List;

@RunWith(SpringRunner.class)
@SpringBootTest(classes = MySpringBootApplication.class)
public class MapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void test() {
        List<User> users = userMapper.queryUserList();
        System.out.println(users);
    }

}

其中,

SpringRunner繼承自SpringJUnit4ClassRunner,使用哪一個Spring提供的測試測試引擎都可以

public final class SpringRunner extends SpringJUnit4ClassRunner

@SpringBootTest的屬性指定的是引導類的字節碼對象

 

5.2.3 控制檯打印信息

 

5.3 SpringBoot整合Spring Data JPA

5.3.1 添加Spring Data JPA的起步依賴

<!-- springBoot JPA的起步依賴 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

### 5.3.2 添加數據庫驅動依賴

<!-- MySQL連接驅動 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>

5.3.3 在application.properties中配置數據庫和jpa的相關屬性

#DB Configuration:
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root

#JPA Configuration:
spring.jpa.database=MySQL
spring.jpa.show-sql=true
spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=update
spring.jpa.hibernate.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy

 5.3.4 創建實體配置實體

@Entity
public class User {
    // 主鍵
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    // 用戶名
    private String username;
    // 密碼
    private String password;
    // 姓名
    private String name;
 
    //此處省略setter和getter方法... ...
}

5.3.5 編寫UserRepository

public interface UserRepository extends JpaRepository<User,Long>{
    public List<User> findAll();
}

5.3.6 編寫測試類

@RunWith(SpringRunner.class)
@SpringBootTest(classes=MySpringBootApplication.class)
public class JpaTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void test(){
        List<User> users = userRepository.findAll();
        System.out.println(users);
    }

}

5.3.7 控制檯打印信息

注意:如果是jdk9,執行報錯如下:

原因:jdk缺少相應的jar

解決方案:手動導入對應的maven座標,如下:

<!--jdk9需要導入如下座標-->
<dependency>
    <groupId>javax.xml.bind</groupId>
    <artifactId>jaxb-api</artifactId>
    <version>2.3.0</version>
</dependency>

 

5.4 SpringBoot整合Redis

 5.4.1 添加redis的起步依賴

<!-- 配置使用redis啓動器 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

5.4.2 配置redis的連接信息

#Redis
spring.redis.host=127.0.0.1
spring.redis.port=6379

5.4.3 注入RedisTemplate測試redis操作

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootJpaApplication.class)
public class RedisTest {

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Test
    public void test() throws JsonProcessingException {
        //從redis緩存中獲得指定的數據
        String userListData = redisTemplate.boundValueOps("user.findAll").get();
        //如果redis中沒有數據的話
        if(null==userListData){
            //查詢數據庫獲得數據
            List<User> all = userRepository.findAll();
            //轉換成json格式字符串
            ObjectMapper om = new ObjectMapper();
            userListData = om.writeValueAsString(all);
            //將數據存儲到redis中,下次在查詢直接從redis中獲得數據,不用在查詢數據庫
            redisTemplate.boundValueOps("user.findAll").set(userListData);
            System.out.println("===============從數據庫獲得數據===============");
        }else{
            System.out.println("===============從redis緩存中獲得數據===============");
        }

        System.out.println(userListData);

    }

}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章