日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

Spring Boot 1.5.2.RELEASE中文版

發布時間:2023/12/9 javascript 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Spring Boot 1.5.2.RELEASE中文版 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Spring Boot 1.5.2.RELEASE中文版

Part I. Spring Boot 文檔

本節簡要介紹了Spring Boot文檔,是整個文檔的參考指南。 您可以完整閱讀本參考指南,或者如果您不感興趣的話可以跳過該部分。

1. 關于文檔

Spring Boot參考指南可以以 html,pdf 和 epub 文檔的形式獲取。 最新版本的文檔可在 http://docs.spring.io/spring-boot/docs/current/reference 中找到。

本文檔您可以自己使用,或發布給別人,印刷版還是以電子形式都可以,但必須包含本版權聲明,不可進行盈利。

2. 獲得幫助

如果使用 Spring Boot 時遇到問題,可以在下面獲取幫助:

  • 嘗試 How-to’s - 這里為最常見的問題提供解決方案。
  • 了解Spring的基礎知識 - Spring Boot建立在許多其他Spring項目上,請查看 spring.io 網站以獲取其他項目的參考文檔。 如果您剛剛開始使用Spring,請閱讀這個指南。
  • 在stackoverflow上提問題 - 我們會一起關注 stackoverflow.com 上有spring-boot標簽的問題。
  • 在Github上報告bug。

Spring Boot 所有的東西都是開源的,包括文檔! 如果您發現文檔有問題; 或者如果你想改進他們,歡迎參與。

3. 第一步

如果你剛剛開始使用 Spring Boot,或剛剛開始使用“Spring”,請從這里開始!

  • 從頭開始:概述 | 要求 | 安裝
  • 教程:Part 1 | Part 2
  • 運行你的例子:Part 1 | Part 2

4. 使用 Spring Boot

  • 構建系統: Maven | Gradle | Ant | Starters
  • 最佳做法:代碼結構 | @Configuration | @EnableAutoConfiguration | Beans 和依賴注入
  • 運行代碼:IDE | Packaged | Maven | Gradle
  • 打包應用程序: Production jars
  • Spring Boot CLI:使用CLI

5. 了解Spring Boot功能

需要有關Spring Boots核心功能的更多細節?請看這里

  • 核心功能: SpringApplication | External Configuration | Profiles | Logging
  • Web 應用: MVC | Embedded Containers
  • 數據處理: SQL | NO-SQL
  • 消息處理: Overview | JMS
  • 測試: Overview | Boot Applications | Utils
  • 擴展: Auto-configuration | @Conditions

6. 轉移到生產環境

當您準備好將Spring Boot 應用程序放到生產環境時,我們有一些您可能會喜歡的技巧!

  • 部署 Spring Boot 應用程序: Cloud Deployment | OS Service 構建工具插件:Maven | Gradle 附錄: Application Properties | 自動配置類 | 可執行 Jars

Part II. 入門指南

如果你剛剛開始使用Spring Boot,這是你的一部分內容! 在這里我們將會回答一些基本的“what?”, “how?” 和 “why?”的問題。 在這里你會找到一個詳細的Spring Boot介紹和安裝說明。 然后,我們將構建我們的第一個Spring Boot應用程序,并討論一些核心原則。

8. Spring Boot 介紹

Spring Boot可以基于Spring輕松創建可以“運行”的、獨立的、生產級的應用程序。 對Spring平臺和第三方類庫我們有自己看法和意見(約定大于配置),所以你最開始的時候不要感到奇怪。大多數Spring Boot應用程序需要很少的Spring配置。

您可以使用Spring Boot創建可以使用java -jar或傳統 war 包部署啟動的Java應用程序。 我們還提供一個運行“spring scripts”的命令行工具。

我們的主要目標是:

  • 為所有的Spring開發者提供一個更快,更廣泛接受的入門體驗。
  • 開始使用開箱即用的配置(極少配置甚至不用配置),但隨著需求開始配置自己所需要的值(即所有配置都有默認值,同時也可以根據自己的需求進行配置)。
  • 提供大量項目中常見的一系列非功能特征(例如嵌入式服務器,安全性,指標,運行狀況檢查,外部化配置)。
  • 絕對沒有代碼生成,也不需要XML配置。

9. 系統要求

默認情況下,Spring Boot 1.5.2.RELEASE需要Java 7和Spring Framework 4.3.7.RELEASE或更高版本。 您可以進行一些其他配置在Java 6上使用Spring Boot。 有關詳細信息,請參見第84.11節“如何使用Java 6”。 為Maven(3.2+)、Gradle 2(2.9或更高版本)和3提供了顯式構建支持。

雖然您可以在Java 6或7上使用 Spring Boot,但我們通常推薦Java 8。

9.1 Servlet容器

以下嵌入式servlet容器可以直接使用:

名稱Servlet 版本Java 版本
Tomcat 83.1Java 7+
Tomcat 73.0Java 6+
Jetty 9.33.1Java 8+
Jetty 9.23.1Java 7+
Jetty 83.0Java 6+
Undertow 1.33.1Java 7+

您還可以將Spring Boot應用程序部署到任何兼容Servlet 3.0+ 的容器中。

10. 安裝 Spring Boot

Spring Boot可以與“經典(classic)”Java開發工具一起使用或作為命令行工具安裝。 無論如何,您將需要Java SDK v1.6或更高版本。 在開始之前檢查當前的Java安裝:

$ java -version

如果您是Java開發的新手,或者您只想嘗試一下 Spring Boot,您可能需要首先嘗試使用 Spring Boot CLI,如果想正式使用Spring Boot,請閱讀“經典(classic)”安裝說明。

雖然Spring Boot 與Java 1.6兼容,但我們建議使用最新版本的Java。

10.1 針對Java開發程序員安裝說明

Spring Boot的使用方式與標準Java庫的使用相同,只需在類路徑中包含適當的spring-boot-*.jar文件。Spring Boot不需要任何特殊的集成工具,所以可以使用任何IDE或文本編輯器進行開發;并且Spring Boot 應用程序沒有什么特殊的地方,因此您可以像其他Java程序一樣運行和調試。雖然您可以直接復制Spring Boot 的jar包,但我們通常建議您使用依賴關系管理的構建工具(如Maven或Gradle)。

10.1.1 Maven安裝

Spring Boot 兼容 Apache Maven 3.2。 如果您還沒有安裝Maven,可以按照 https://maven.apache.org/ 上的說明進行安裝。

在許多操作系統上,Maven可以通過軟件包管理器進行安裝。 如果您是OSX Homebrew用戶,請嘗試使用命令:brew install maven。 Ubuntu用戶可以運行命令:sudo apt-get install maven。

Spring Boot 依賴 org.springframework.boot groupId。通常,您的Maven POM文件將從 spring-boot-starter-parent 項目繼承,并聲明一個或多個“啟動器(啟動器)”的依賴關系。Spring Boot還提供了一個可選的Maven插件來創建可執行的jar包。

典型的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> <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.example<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>myproject<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>0.0.1-SNAPSHOT<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><span class="hljs-comment">&lt;!-- Inherit defaults from Spring Boot --&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">parent</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.5.2.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">parent</span>&gt;</span><span class="hljs-comment">&lt;!-- Add typical dependencies for a web application --&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-web<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span><span class="hljs-comment">&lt;!-- Package as an executable jar --&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">build</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">plugins</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">plugin</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-maven-plugin<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">plugin</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">plugins</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">build</span>&gt;</span>

</project>

spring-boot-starter-parent是使用Spring Boot的一個很好的方式,但它并不是所有的時候都適合。有時您可能需要從不同的父POM繼承,或者您可能不喜歡我們的默認設置。 請參見第13.2.2節“使用不帶父POM的Spring Boot”作為使用導入作用域(import scope)的替代解決方案。

10.1.2 Gradle 安裝

Spring Boot 兼容 Gradle 2(2.9或更高版本)和Gradle 3。如果您尚未安裝Gradle,您可以按照 http://www.gradle.org/ 上的說明進行操作。

可以使用org.springframework.boot 組(group)聲明Spring Boot 的依賴項。 通常,您的項目將聲明一個或多個“啟動器(Starters)”的依賴。Spring Boot提供了一個有用的Gradle插件,可用于簡化依賴關系聲明和創建可執行 jar包。

Gradle Wrapper

當您需要構建項目時,Gradle Wrapper提供了一種“獲取(obtaining)”Gradle的更好的方式。 它是一個小腳本和庫,它與代碼一起引導構建過程。 有關詳細信息,請參閱 https://docs.gradle.org/2.14.1/userguide/gradle_wrapper.html 。

典型的 build.gradle 文件:

plugins {id 'org.springframework.boot' version '1.5.2.RELEASE'id 'java' }

jar {
baseName = ‘myproject’
version = ‘0.0.1-SNAPSHOT’
}

repositories {
jcenter()
}

dependencies {
compile(“org.springframework.boot:spring-boot-starter-web”)
testCompile(“org.springframework.boot:spring-boot-starter-test”)
}

10.2 安裝Spring Boot CLI

Spring Boot CLI是一個命令行工具,如果要使用Spring快速原型(quickly prototype),可以使用它。 它允許您運行Groovy腳本,這意味著會有您熟悉的類似Java的語法,沒有太多的樣板代碼(boilerplate code)。

您也不必要通過CLI來使用Spring Boot,但它絕對是開始Spring應用程序最快方法。

10.2.1 手動安裝

您可以從Spring軟件版本庫下載Spring CLI發行版:

  • spring-boot-cli-1.5.2.RELEASE-bin.zip
  • spring-boot-cli-1.5.2.RELEASE-bin.tar.gz

各發布版本的快照。

下載完成后,請按照解壓縮后文件中的INSTALL.txt的說明進行操作。 總而言之:在.zip文件的bin/目錄中有一個spring腳本(Windows的spring.bat),或者你可以使用java -jar(腳本可以幫助您確保類路徑設置正確)。

10.2.2 使用SDKMAN!安裝

SDKMAN!(軟件開發套件管理器)可用于管理各種二進制SDK的多個版本,包括Groovy和Spring Boot CLI。從http://sdkman.io/ 獲取SDKMAN!并安裝Spring Boot。

$ sdk install springboot $ spring --version Spring Boot v1.5.2.RELEASE

如果您正在開發CLI的功能,并希望輕松訪問剛創建的版本,請遵循以下額外說明。

$ sdk install springboot dev /path/to/spring-boot/spring-boot-cli/target/spring-boot-cli-1.5.2.RELEASE-bin/spring-1.5.2.RELEASE/ $ sdk default springboot dev $ spring --version Spring CLI v1.5.2.RELEASE

這將安裝一個稱為dev的spring的本地實例(instance)。 它指向您構建位置的target,所以每次重建(rebuild)Spring Boot時,Spring 將是最新的。

你可以看到:

$ sdk ls springboot

================================================================================
Available Springboot Versions

> + dev

  • 1.5.2.RELEASE

================================================================================

    • local version
    • installed
      > - currently in use
      ================================================================================

10.2.3 OSX Homebrew 安裝

如果您在Mac上使用 Homebrew,安裝Spring Boot CLI 只需要下面命令:

$ brew tap pivotal/tap $ brew install springboot

Homebrew會將Spring 安裝到 /usr/local/bin。

如果您沒有看到公式(formula),您的安裝可能會過期。 只需執行brew更新,然后重試。

10.2.4 MacPorts安裝

如果您在Mac上使用 MacPorts,安裝Spring Boot CLI 只需要下面命令:

$ sudo port install spring-boot-cli

10.2.5 命令行提示

Spring Boot CLI為BASH和zsh shell提供命令提示的功能。 您可以在任何shell中引用腳本(也稱為spring),或將其放在您的個人或系統范圍的bash完成初始化中。 在Debian系統上,系統范圍的腳本位于 /shell-completion/bash 中,當新的shell啟動時,該目錄中的所有腳本將被執行。 手動運行腳本,例如 如果您使用SDKMAN安裝了!

$ . ~/.sdkman/candidates/springboot/current/shell-completion/bash/spring $ spring <HIT TAB HERE>grab help jar run test version

如果使用Homebrew或MacPorts安裝Spring Boot CLI,則命令行補全腳本將自動注冊到您的shell。

10.2.6 快速啟動Spring CLI示例

這是一個非常簡單的Web應用程序,可用于測試您的安裝是否正確。 創建一個名為app.groovy的文件:

@RestController class ThisWillActuallyRun { <span class="hljs-meta">@RequestMapping</span>(<span class="hljs-string">"/"</span>) <span class="hljs-function">String <span class="hljs-title">home</span><span class="hljs-params">()</span> </span>{<span class="hljs-string">"Hello World!"</span> }

}

然后從shell運行它:

$ spring run app.groovy

因為下載依賴的庫,首次運行應用程序需要一些時間,。 后續運行將會更快。

在瀏覽器中打開 http://localhost:8080 ,您應該會看到以下輸出:

Hello World!

10.3 從早期版本的Spring Boot升級

如果您從早期版本的 Spring Boot 升級,請檢查項目wiki上托管的“發行說明”。 您將找到升級說明以及每個版本的“新的和值得注意的”功能的列表。

要升級現有的CLI安裝,請使用包管理工具相應的package manager命令(例如brew upgrade),如果您手動安裝了CLI,請按照標準說明記住更新PATH環境變量以刪除任何舊的引用。

11. 開發您的第一個Spring Boot應用程序

讓我們在Java中開發一個簡單的“Hello World!”Web應用程序,突顯Spring Boot一些主要的功能。 我們將使用Maven構建該項目,因為大多數IDE支持它。

https://spring.io/ 包含許多使用Spring Boot的“入門指南”。 如果您正在尋求解決一些具體問題; 可以先看一下那里。

您可以在 https://start.spring.io/ 的依賴關系搜索器中選擇Web啟動器來快速完成以下步驟。 這會自動生成一個新的項目結構,方便您立即開始編碼。 查看文檔了解更多詳細信息。

在開始之前,打開終端來檢查您是否安裝了有效的Java和Maven版本。

$ java -version java version "1.7.0_51" Java(TM) SE Runtime Environment (build 1.7.0_51-b13) Java HotSpot(TM) 64-Bit Server VM (build 24.51-b03, mixed mode)

$ mvn -v
Apache Maven 3.2.3 (33f8c3e1027c3ddde99d3cdebad2656a31e8fdf4; 2014-08-11T13:58:10-07:00)
Maven home: /Users/user/tools/apache-maven-3.1.1
Java version: 1.7.0_51, vendor: Oracle Corporation

這個示例需要在其自己的文件夾中創建。 后面我們假設您在當前目錄已經創建了一個正確的文件夾。

11.1 創建POM

我們需要先創建一個Maven pom.xml文件。 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> <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>com.example<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>myproject<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span> <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>0.0.1-SNAPSHOT<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">parent</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.5.2.RELEASE<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">parent</span>&gt;</span><span class="hljs-comment">&lt;!-- Additional lines to be added here... --&gt;</span>

</project>

這應該給你一個工作構建(working build),你可以通過運行 mvn package 進行測試(你可以暫時忽略警告:“jar will be empty - no content was marked for inclusion!”)。

現在,您可以將項目導入到IDE中(最新的Java IDE內置對Maven的支持)。 為了簡單起見,這個示例我們繼續使用純文本編輯器。

11.2 添加類路徑依賴關系

Spring Boot提供了一些“啟動器(Starters)”,可以方便地將jar添加到類路徑中。我們的示例應用程序已經在POM的父部分使用了spring-boot-starter-parent。spring-boot-starter-parent是一個特殊啟動器,提供一些Maven的默認值。它還提供依賴管理 dependency-management 標簽,以便您可以省略子模塊依賴關系的版本標簽。

其他“啟動器(Starters)”只是提供您在開發特定類型的應用程序時可能需要的依賴關系。 由于我們正在開發Web應用程序,所以我們將添加一個spring-boot-starter-web依賴關系,但在此之前,我們來看看我們目前的依賴。

$ mvn dependency:tree

[INFO] com.example:myproject:jar:0.0.1-SNAPSHOT

mvn dependency:tree:打印項目依賴關系的樹形表示。 您可以看到spring-boot-starter-parent本身不在依賴關系中。 編輯pom.xml并在 parent 下添加spring-boot-starter-web依賴關系:

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

如果您再次運行 mvn dependency:tree ,您將看到現在有許多附加依賴關系,包括Tomcat Web服務器和Spring Boot本身。

11.3 編寫代碼

要完成我們的應用程序,我們需要創建一個的Java文件。 默認情況下,Maven將從src/main/java編譯源代碼,因此您需要創建該文件夾結構,然后添加一個名為src/main/java/Example.java的文件:

import org.springframework.boot.*; import org.springframework.boot.autoconfigure.*; import org.springframework.stereotype.*; import org.springframework.web.bind.annotation.*;

@RestController
@EnableAutoConfiguration
public class Example {

<span class="hljs-meta">@RequestMapping</span>(<span class="hljs-string">"/"</span>) <span class="hljs-function">String <span class="hljs-title">home</span><span class="hljs-params">()</span> </span>{<span class="hljs-keyword">return</span> <span class="hljs-string">"Hello World!"</span>; }<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> <span class="hljs-keyword">throws</span> Exception </span>{SpringApplication.run(Example.class, args); }

}

雖然這里沒有太多的代碼,但是有一些重要的部分。

11.3.1 @RestController和@RequestMapping 注解

我們的Example類的第一個注解是@RestController。 這被稱為 stereotype annotation。它為人們閱讀代碼提供了一些提示,對于Spring來說,這個類具有特定的作用。在這里,我們的類是一個web @Controller,所以Spring在處理傳入的Web請求時會考慮這個類。

@RequestMapping注解提供“路由”信息。 告訴Spring,任何具有路徑“/”的HTTP請求都應映射到home方法。 @RestController注解告訴Spring將生成的字符串直接返回給調用者。

@RestController和@RequestMapping注解是Spring MVC 的注解(它們不是Spring Boot特有的)。 有關更多詳細信息,請參閱Spring參考文檔中的MVC部分。

11.3.2 @EnableAutoConfiguration注解

第二個類級別的注釋是@EnableAutoConfiguration。 這個注解告訴 Spring Boot 根據您添加的jar依賴關系來“猜(guess)”你將如何配置Spring。由于spring-boot-starter-web添加了Tomcat和Spring MVC,自動配置將假定您正在開發Web應用程序并相應地配置Spring。

啟動器和自動配置

自動配置旨在與“起動器”配合使用,但兩個概念并不直接相關。 您可以自由選擇啟動器之外的jar依賴項,Spring Boot仍然會自動配置您的應用程序。

11.3.3 “main”方法

我們的應用程序的最后一部分是main()方法。 這只是一個遵循Java慣例的應用程序入口點的標準方法。 我們的main()方法通過調用run()委托(delegates)給Spring Boot的SpringApplication類。 SpringApplication將引導我們的應用程序,啟動Spring,然后啟動自動配置的Tomcat Web服務器。 我們需要將Example.class作為一個參數傳遞給run方法來告訴SpringApplication,它是主要的Spring組件。 還傳遞了args數組以傳遞命令行參數。

11.4 運行示例

由于我們使用了spring-boot-starter-parent POM,所以我們有一個可用的運行目標,我們可以使用它來啟動應用程序。 鍵入mvn spring-boot:從根目錄運行以啟動應用程序:

$ mvn spring-boot:run

. ____ _ __ _ _
/\ / ’ __ _ () __ __ _ \ \ \
( ( )__ | '_ | '| | ’ / ` | \ \ \
\/ )| |)| | | | | || (| | ) ) ) )
’ || .__|| ||| |__, | / / / /
=|_|======|/=////
:: Spring Boot :: (v1.5.2.RELEASE)
… . . .
… . . . (log output here)
… . . .
… Started Example in 2.222 seconds (JVM running for 6.514)

如果你用瀏覽器打開 http://localhost:8080 你應該看到以下輸出:

Hello World!

ctrl-c 正常(gracefully)退出應用程序。

11.5 創建可執行的jar

讓我們完成我們的例子,創建一個完全自包含的可執行jar文件,我們可以在生產環境中運行。 可執行的jar(有時稱為“fat jars”)是包含編譯的類以及代碼運行所需要的所有jar包依賴的歸檔(archives)。

可執行jar和Java

Java不提供任何標準的方法來加載嵌套的jar文件(即本身包含在jar中的jar文件)。 如果您正在尋找可以發布自包含的應用程序,這可能是有問題的。 為了解決這個問題,許多開發人員使用“uber” jars。 一個uber jar簡單地將所有類、jar包進行檔案。 這種方法的問題是,很難看到您在應用程序中實際使用哪些庫。 如果在多個jar中使用相同的文件名(但具有不同的內容),也可能會出現問題。 Spring Boot采用一個不同的方法這樣可以直接對jar進行嵌套。

要創建可執行的jar,我們需要將spring-boot-maven-plugin添加到我們的pom.xml中。 在 dependencies標簽 下方插入以下行:

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

spring-boot-starter-parent POM 包括重新打包目標的 executions標簽 配置。 如果您不使用該父POM,您將需要自己聲明此配置。 有關詳細信息,請參閱插件文檔。

保存您的pom.xml并從命令行運行 mvn package:

$ mvn package

[INFO] Scanning for projects…
[INFO]
[INFO] ------------------------------------------------------------------------
[INFO] Building myproject 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[INFO] … …
[INFO] — maven-jar-plugin:2.4:jar (default-jar) @ myproject —
[INFO] Building jar: /Users/developer/example/spring-boot-example/target/myproject-0.0.1-SNAPSHOT.jar
[INFO]
[INFO] — spring-boot-maven-plugin:1.5.2.RELEASE:repackage (default) @ myproject —
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

如果你看看target目錄,你應該看到myproject-0.0.1-SNAPSHOT.jar。 該文件的大小約為10 MB。 如果你想查看里面,可以使用jar tvf:

$ jar tvf target/myproject-0.0.1-SNAPSHOT.jar

您還應該在target目錄中看到一個名為myproject-0.0.1-SNAPSHOT.jar.original的較小文件。 這是Maven在Spring Boot重新打包之前創建的原始jar文件。

使用java -jar命令運行該應用程序:

$ java -jar target/myproject-0.0.1-SNAPSHOT.jar

. ____ _ __ _ _
/\ / ’ __ _ () __ __ _ \ \ \
( ( )__ | '_ | '| | ’ / ` | \ \ \
\/ )| |)| | | | | || (| | ) ) ) )
’ || .__|| ||| |__, | / / / /
=|_|======|/=////
:: Spring Boot :: (v1.5.2.RELEASE)
… . . .
… . . . (log output here)
… . . .
… Started Example in 2.536 seconds (JVM running for 2.864)

像之前一樣,ctrl+c正常退出應用程序。

12. 接下來應該讀什么

希望本節能為您提供一些Spring Boot基礎知識,并讓您準備編寫自己的應用程序。 如果你是一個面向具體任務的開發人員,你可能想跳過 https://spring.io/ ,看看一些解決具體的“如何用Spring”問題的入門指南; 我們還有Spring Boot-specific How-to參考文檔。

Spring Boot庫還有一大堆可以運行的示例。 示例與代碼的其余部分是獨立的(這樣您不需要構建多余的代碼來運行或使用示例)。

下一個是第三部分“使用 Spring Boot”。 如果你真的沒有這個耐心,也可以跳過去閱讀Spring Boot功能。

Part III. 使用 Spring Boot

本部分將詳細介紹如何使用Spring Boot。 這部分涵蓋諸如構建系統,自動配置以及如何運行應用程序等主題。 我們還介紹了一些Spring Boot的最佳實踐(best practices)。 雖然Spring Boot沒有什么特殊之處(它只是一個可以使用的庫),但是有一些建議可以讓您的開發過程更容易一些。

如果您剛剛開始使用Spring Boot,那么在深入本部分之前,您應該閱讀入門指南。

13. 構建系統

強烈建議您選擇一個支持依賴管理并可以使用“Maven Central”存儲庫的構建系統。 我們建議您選擇Maven或Gradle。 Spring Boot 可以與其他構建系統(例如 Ant )配合使用,但是它們不會得到很好的支持。

13.1 依賴管理

每個版本的Spring Boot提供了一個它所支持的依賴關系列表。 實際上,您不需要為構建配置文件中的這些依賴關系提供版本,因為Spring Boot會為您進行管理這些依賴的版本。 當您升級Spring Boot本身時,這些依賴關系也將以一致的進行升級。

如果您覺得有必要,您仍然可以指定一個版本并覆蓋Spring Boot建議的版本。

管理的列表中包含可以使用Spring Boot的所有Spring模塊以及第三方庫的精簡列表。 該列表可作為標準的物料(Materials)清單(spring-boot-dependencies)使用,并且還提供了對 Maven 和 Gradle 的額外支持。

Spring Boot的每個版本與Spring Framework的基本版本相關聯,因此我們強烈建議您不要自己指定其版本。

13.2 Maven

Maven用戶可以從 spring-boot-starter-parent-parent 項目中繼承,以獲得合理的默認值。 父項目提供以下功能:

  • Java 1.6作為默認編譯器級別。
  • 源代碼UTF-8編碼。
  • 依賴關系管理,允許您省略常見依賴的<version>標簽,其默認版本繼承自spring-boot-dependencies POM。
  • 更合理的資源過濾。
  • 更合理的插件配置(exec plugin,surefire,Git commit ID,shade)。
  • 針對application.properties和application.yml的更合理的資源過濾,包括特定的文件(例如application-foo.properties和application-foo.yml)
  • 最后一點:由于默認的配置文件接受Spring樣式占位符(${...}),Maven過濾更改為使用 @..@ 占位符(您可以使用Maven屬性resource.delimiter覆蓋它)。

13.2.1 繼承啟動器parent

要將項目配置為繼承spring-boot-starter-parent,只需設置<parent>標簽如下:

<!-- Inherit defaults from Spring Boot --> <parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>1.5.2.RELEASE</version> </parent>

您只需要在此依賴項上指定Spring Boot版本號。 如果您導入其他起始器,則可以放心地省略他們的版本號。

通過該設置,您還可以通過覆蓋自己的項目中的屬性來覆蓋單個依賴。 例如,要升級到另一個 Spring Data 版本序列,您需要將以下內容添加到您的pom.xml中。

<properties><spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version> </properties>

檢查 spring-boot-dependencies pom 以獲取支持的屬性列表。

13.2.2 使用沒有父POM的 Spring Boot

不是每個人都喜歡從spring-boot-starter-parent POM繼承。 您公司可能有自己標準的父母,或者您可能只希望明確聲明所有的Maven配置。

如果您不想使用spring-boot-starter-parent,則仍然可以通過使用scope=import依賴來保持依賴管理(但不能進行插件管理)的好處:

<dependencyManagement><dependencies><dependency><!-- Import dependency management from Spring Boot --><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>1.5.2.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies> </dependencyManagement>

該設置不允許您使用如13.2.1 所述的屬性來覆蓋單個依賴關系。 要實現相同的結果,您需要在spring-boot-dependencies條目之前在項目的dependencyManagement中添加一個條目。 例如,要升級到另一個Spring Data發行版本,您需要將以下內容添加到您的pom.xml中。

<dependencyManagement><dependencies><!-- Override Spring Data release train provided by Spring Boot --><dependency><groupId>org.springframework.data</groupId><artifactId>spring-data-releasetrain</artifactId><version>Fowler-SR2</version><scope>import</scope><type>pom</type></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-dependencies</artifactId><version>1.5.2.RELEASE</version><type>pom</type><scope>import</scope></dependency></dependencies> </dependencyManagement>

在上面的例子中,我們指定了一個BOM,但是任何依賴關系類型都可以被這樣覆蓋。

13.2.3 更改Java版本

spring-boot-starter-parent選擇相當保守的Java兼容性版本。 如果要遵循我們的建議并使用更高版本的Java版本,可以添加java.version屬性:

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

13.2.4 使用Spring Boot Maven插件

Spring Boot包括一個Maven插件,可以將項目打包成可執行jar。 如果要使用它,請將插件添加到<plugins>部分:

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

如果您使用Spring Boot啟動器 parent pom,則只需要添加這個插件,除非您要更改parent中定義的設置,否則不需要進行配置。

13.3 Gradle

Gradle用戶可以直接在其依賴關系部分導入“啟動器”。 不像Maven,沒有“超級父”導入來共享一些配置。

repositories {jcenter() }

dependencies {
compile(“org.springframework.boot:spring-boot-starter-web:1.5.2.RELEASE”)
}

spring-boot-gradle-plugin也是可用的,它提供了從源代碼創建可執行jar并運行項目的任務。 它還提供依賴關系管理,除其他功能外,還允許您省略由Spring Boot管理的任何依賴關系的版本號:

plugins {id 'org.springframework.boot' version '1.5.2.RELEASE'id 'java' }

repositories {
jcenter()
}

dependencies {
compile(“org.springframework.boot:spring-boot-starter-web”)
testCompile(“org.springframework.boot:spring-boot-starter-test”)
}

13.4 Ant

可以使用Apache Ant + Ivy構建Spring Boot項目。 spring-boot-antlib“AntLib”模塊也可用于幫助Ant創建可執行文件。

要聲明依賴關系,典型的ivy.xml文件將如下所示:

<ivy-module version="2.0"><info organisation="org.springframework.boot" module="spring-boot-sample-ant" /><configurations><conf name="compile" description="everything needed to compile this module" /><conf name="runtime" extends="compile" description="everything needed to run this module" /></configurations><dependencies><dependency org="org.springframework.boot" name="spring-boot-starter"rev="${spring-boot.version}" conf="compile" /></dependencies> </ivy-module>

典型的build.xml將如下所示:

<projectxmlns:ivy="antlib:org.apache.ivy.ant"xmlns:spring-boot="antlib:org.springframework.boot.ant"name="myapp" default="build"> <span class="hljs-tag">&lt;<span class="hljs-name">property</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"spring-boot.version"</span> <span class="hljs-attr">value</span>=<span class="hljs-string">"1.3.0.BUILD-SNAPSHOT"</span> /&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">target</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"resolve"</span> <span class="hljs-attr">description</span>=<span class="hljs-string">"--&gt; retrieve dependencies with ivy"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">ivy:retrieve</span> <span class="hljs-attr">pattern</span>=<span class="hljs-string">"lib/[conf]/[artifact]-[type]-[revision].[ext]"</span> /&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">target</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">target</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"classpaths"</span> <span class="hljs-attr">depends</span>=<span class="hljs-string">"resolve"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">path</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"compile.classpath"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">fileset</span> <span class="hljs-attr">dir</span>=<span class="hljs-string">"lib/compile"</span> <span class="hljs-attr">includes</span>=<span class="hljs-string">"*.jar"</span> /&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">path</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">target</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">target</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"init"</span> <span class="hljs-attr">depends</span>=<span class="hljs-string">"classpaths"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">mkdir</span> <span class="hljs-attr">dir</span>=<span class="hljs-string">"build/classes"</span> /&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">target</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">target</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"compile"</span> <span class="hljs-attr">depends</span>=<span class="hljs-string">"init"</span> <span class="hljs-attr">description</span>=<span class="hljs-string">"compile"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">javac</span> <span class="hljs-attr">srcdir</span>=<span class="hljs-string">"src/main/java"</span> <span class="hljs-attr">destdir</span>=<span class="hljs-string">"build/classes"</span> <span class="hljs-attr">classpathref</span>=<span class="hljs-string">"compile.classpath"</span> /&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">target</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">target</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"build"</span> <span class="hljs-attr">depends</span>=<span class="hljs-string">"compile"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">spring-boot:exejar</span> <span class="hljs-attr">destfile</span>=<span class="hljs-string">"build/myapp.jar"</span> <span class="hljs-attr">classes</span>=<span class="hljs-string">"build/classes"</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">spring-boot:lib</span>&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">fileset</span> <span class="hljs-attr">dir</span>=<span class="hljs-string">"lib/runtime"</span> /&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">spring-boot:lib</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">spring-boot:exejar</span>&gt;</span> <span class="hljs-tag">&lt;/<span class="hljs-name">target</span>&gt;</span>

</project>

請參見第84.10節“從Ant構建可執行存檔,而不使用spring-boot-antlib”如果不想使用spring-boot-antlib模塊,請參閱“操作方法”。

13.5 啟動器

啟動器是一組方便的依賴關系描述符,可以包含在應用程序中。 您可以獲得所需的所有Spring和相關技術的一站式服務,無需通過示例代碼搜索和復制粘貼依賴配置。 例如,如果要開始使用Spring和JPA進行數據庫訪問,那么只需在項目中包含spring-boot-starter-data-jpa依賴關系即可。

啟動器包含許多依賴關系,包括您需要使項目快速啟動并運行,并具有一致的受支持的依賴傳遞關系。

What’s in a name

所有正式起動器都遵循類似的命名模式: spring-boot-starter- * ,其中 * 是特定類型的應用程序。 這個命名結構旨在幫助你快速找到一個啟動器。 許多IDE中的Maven插件允許您按名稱搜索依賴項。 例如,安裝Eclipse或STS的Maven插件后,您可以簡單地在POM編輯器中點擊 Dependency Hierarchy,并在filter輸入“spring-boot-starter”來獲取完整的列表。 如創建自己的啟動器部分所述,第三方啟動程序不應該從Spring-boot開始,因為它是為正式的Spring Boot artifacts 保留的。 acme 的 第三方啟動器通常被命名為acme-spring-boot-starter。

Spring Boot在org.springframework.boot組下提供了以下應用程序啟動器:

表13.1. Spring Boot應用程序啟動器

名稱描述Pom
spring-boot-starter-thymeleaf使用Thymeleaf視圖構建MVC Web應用程序的啟動器Pom
spring-boot-starter-data-couchbase使用Couchbase面向文檔的數據庫和Spring Data Couchbase的啟動器Pom
spring-boot-starter-artemis使用Apache Artemis的JMS啟動器Pom
spring-boot-starter-web-servicesSpring Web Services 啟動器Pom
spring-boot-starter-mailJava Mail和Spring Framework的電子郵件發送支持的啟動器Pom
spring-boot-starter-data-redisRedis key-value 數據存儲與Spring Data Redis和Jedis客戶端啟動器Pom
spring-boot-starter-web使用Spring MVC構建Web,包括RESTful應用程序。使用Tomcat作為默認的嵌入式容器的啟動器Pom
spring-boot-starter-data-gemfire使用GemFire分布式數據存儲和Spring Data GemFire的啟動器Pom
spring-boot-starter-activemq使用Apache ActiveMQ的JMS啟動器Pom
spring-boot-starter-data-elasticsearch使用Elasticsearch搜索和分析引擎和Spring Data Elasticsearch的啟動器Pom
spring-boot-starter-integrationSpring Integration 啟動器Pom
spring-boot-starter-test使用JUnit,Hamcrest和Mockito的庫測試Spring Boot應用程序的啟動器Pom
spring-boot-starter-jdbc使用JDBC與Tomcat JDBC連接池的啟動器Pom
spring-boot-starter-mobile使用Spring Mobile構建Web應用程序的啟動器Pom
spring-boot-starter-validation使用Java Bean Validation 與Hibernate Validator的啟動器Pom
spring-boot-starter-hateoas使用Spring MVC和Spring HATEOAS構建基于超媒體的RESTful Web應用程序的啟動器Pom
spring-boot-starter-jersey使用JAX-RS和Jersey構建RESTful Web應用程序的啟動器。spring-boot-starter-web的替代方案Pom
spring-boot-starter-data-neo4j使用Neo4j圖數據庫和Spring Data Neo4j的啟動器Pom
spring-boot-starter-data-ldap使用Spring Data LDAP的啟動器Pom
spring-boot-starter-websocket使用Spring Framework的WebSocket支持構建WebSocket應用程序的啟動器Pom
spring-boot-starter-aop使用Spring AOP和AspectJ進行面向切面編程的啟動器Pom
spring-boot-starter-amqp使用Spring AMQP和Rabbit MQ的啟動器Pom
spring-boot-starter-data-cassandra使用Cassandra分布式數據庫和Spring Data Cassandra的啟動器Pom
spring-boot-starter-social-facebook使用Spring Social Facebook 的啟動器Pom
spring-boot-starter-jta-atomikos使用Atomikos的JTA事務的啟動器Pom
spring-boot-starter-security使用Spring Security的啟動器Pom
spring-boot-starter-mustache使用Mustache視圖構建MVC Web應用程序的啟動器Pom
spring-boot-starter-data-jpa使用Spring數據JPA與Hibernate的啟動器Pom
spring-boot-starter核心啟動器,包括自動配置支持,日志記錄和YAMLPom
spring-boot-starter-groovy-templates使用Groovy模板視圖構建MVC Web應用程序的啟動器Pom
spring-boot-starter-freemarker使用FreeMarker視圖構建MVC Web應用程序的啟動器Pom
spring-boot-starter-batch使用Spring Batch的啟動器Pom
spring-boot-starter-social-linkedin使用Spring Social LinkedIn的啟動器Pom
spring-boot-starter-cache使用Spring Framework緩存支持的啟動器Pom
spring-boot-starter-data-solr使用Apache Solr搜索平臺與Spring Data Solr的啟動器Pom
spring-boot-starter-data-mongodb使用MongoDB面向文檔的數據庫和Spring Data MongoDB的啟動器Pom
spring-boot-starter-jooq使用jOOQ訪問SQL數據庫的啟動器。 spring-boot-starter-data-jpa或spring-boot-starter-jdbc的替代方案Pom
spring-boot-starter-jta-narayanaSpring Boot Narayana JTA 啟動器Pom
spring-boot-starter-cloud-connectors使用Spring Cloud連接器,簡化了與Cloud Foundry和Heroku等云平臺中的服務連接的啟動器Pom
spring-boot-starter-jta-bitronix使用Bitronix進行JTA 事務的啟動器Pom
spring-boot-starter-social-twitter使用Spring Social Twitter的啟動器Pom
spring-boot-starter-data-rest通過使用Spring Data REST在REST上暴露Spring數據庫的啟動器Pom

除了應用程序啟動器,以下啟動器可用于添加生產準備(production ready)功能:

表13.2 Spring Boot生產環境啟動器

名稱描述Pom
spring-boot-starter-actuator使用Spring Boot Actuator提供生產準備功能,可幫助您監控和管理應用程序的啟動器Pom
spring-boot-starter-remote-shell使用CRaSH遠程shell通過SSH監視和管理您的應用程序的啟動器。 自1.5以來已棄用Pom

最后,Spring Boot還包括一些啟動器,如果要排除或替換特定的技術,可以使用它們:

名稱描述Pom
spring-boot-starter-undertow使用Undertow作為嵌入式servlet容器的啟動器。 spring-boot-starter-tomcat的替代方案Pom
spring-boot-starter-jetty使用Jetty作為嵌入式servlet容器的啟動器。 spring-boot-starter-tomcat的替代方案Pom
spring-boot-starter-logging使用Logback進行日志記錄的啟動器。 默認的日志啟動器Pom
spring-boot-starter-tomcat使用Tomcat作為嵌入式servlet容器的啟動器。 spring-boot-starter-web的默認servlet容器啟動器Pom
spring-boot-starter-log4j2使用Log4j2進行日志記錄的啟動器。 spring-boot-start-logging的替代方法Pom

有關社區貢獻的更多啟動器的列表,請參閱GitHub上的spring-boot-startters模塊中的README文件。

14. 構建代碼

Spring Boot不需要任何特定的代碼組織結構,但是有一些最佳實踐可以幫助您。

14.1 不要使用“default”包

當類不包括包聲明時,它被認為是在“默認包”中。 通常不鼓勵使用“默認包”,并應該避免使用。 對于使用@ComponentScan,@EntityScan或@SpringBootApplication注解的Spring Boot應用程序,可能會有一些特殊的問題,因為每個jar的每個類都將被讀取。

我們建議您遵循Java推薦的軟件包命名約定,并使用反向域名(例如,com.example.project)。

14.2 查找主應用程序類

我們通常建議您將應用程序主類放到其他類之上的根包(root package)中。 @EnableAutoConfiguration注解通常放置在您的主類上,它隱式定義了某些項目的基本“搜索包”。 例如,如果您正在編寫JPA應用程序,則@EnableAutoConfiguration注解類的包將用于搜索@Entity項。

使用根包(root package)還可以使用@ComponentScan注釋,而不需要指定basePackage屬性。 如果您的主類在根包中,也可以使用@SpringBootApplication注釋。

這是一個典型的布局:

com+- example+- myproject+- Application.java|+- domain| +- Customer.java| +- CustomerRepository.java|+- service| +- CustomerService.java|+- web+- CustomerController.java

Application.java文件將聲明main方法以及基本的@Configuration。

package com.example.myproject;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{SpringApplication.run(Application.class, args); }

}

15. 配置類

Spring Boot支持基于Java的配置。雖然可以使用XML配置用SpringApplication.run(),但我們通常建議您的主source是@Configuration類。 通常,定義main方法的類也是作為主要的@Configuration一個很好的選擇。

許多使用XML配置的Spring示例已經在網上發布。 如果可能的話我們建議始終嘗試使用等效的基于Java的配置。 搜索 enable* 注解可以是一個很好的起點。

15.1 導入其他配置類

您不需要將所有的@Configuration放在一個類中。 @Import注解可用于導入其他配置類。 或者,您可以使用@ComponentScan自動掃描所有Spring組件,包括@Configuration類。

15.2 導入XML配置

如果您必須使用基于XML的配置,我們建議您仍然從@Configuration類開始。 然后,您可以使用的@ImportResource注釋來加載XML配置文件。

16. 自動配置

Spring Boot 會根據您添加的jar依賴關系自動配置您的Spring應用程序。例如,如果HSQLDB在您的類路徑上,并且您沒有手動配置任何數據庫連接bean,那么我們將自動配置內存數據庫。

您需要通過將@EnableAutoConfiguration或@SpringBootApplication注解添加到您的一個@Configuration類中來選擇自動配置。

您應該只添加一個@EnableAutoConfiguration注解。 我們通常建議您將其添加到主@Configuration類中。

16.1逐漸取代自動配置

自動配置是非侵入式的,您可以隨時定義自己的配置來替換自動配置。 例如,如果您添加自己的 DataSource bean,則默認的嵌入式數據庫支持將會退回。

如果您需要了解當前有哪些自動配置,以及為什么,請使用--debug開關啟動應用程序。 這將啟用debug日志,并將自動配置日志記錄到控制臺。

16.2 禁用指定的自動配置

如果您發現正在使用一些不需要的自動配置類,可以使用@EnableAutoConfiguration的exclude屬性來禁用它們。

import org.springframework.boot.autoconfigure.*; import org.springframework.boot.autoconfigure.jdbc.*; import org.springframework.context.annotation.*;

@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}

如果類不在classpath路徑上,則可以使用注釋的excludeName屬性,并指定全限定名(fully qualified name)。 最后,您還可以通過spring.autoconfigure.exclude屬性控制要排除的自動配置類列表。

注解和使用屬性(property)定義都可以指定要排除的自動配置類。

17. Spring Beans 和 依賴注入

您可以自由使用任何標準的Spring Framework技術來定義您的bean及其依賴注入關系。 為了簡單起見,我們發現使用@ComponentScan搜索bean,結合@Autowired構造函數(constructor)注入效果很好。

如果您按照上述建議(將應用程序類放在根包(root package)中)構建代碼,則可以使用 @ComponentScan而不使用任何參數。 所有應用程序組件(@Component,@Service,@Repository,@Controller等)將自動注冊為Spring Bean。

以下是一個@Service Bean的例子,我們可以使用構造函數注入獲取RiskAssessor bean。

package com.example.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class DatabaseAccountService implements AccountService {

<span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> RiskAssessor riskAssessor;<span class="hljs-meta">@Autowired</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">DatabaseAccountService</span><span class="hljs-params">(RiskAssessor riskAssessor)</span> </span>{<span class="hljs-keyword">this</span>.riskAssessor = riskAssessor; }<span class="hljs-comment">// ...</span>

}

如果一個bean 只有一個構造函數,則可以省略@Autowired。

@Service public class DatabaseAccountService implements AccountService { <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> RiskAssessor riskAssessor;<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">DatabaseAccountService</span><span class="hljs-params">(RiskAssessor riskAssessor)</span> </span>{<span class="hljs-keyword">this</span>.riskAssessor = riskAssessor; }<span class="hljs-comment">// ...</span>

}

注意,如何使用構造函數注入允許將RiskAssessor字段標記為final,表示不能更改。

18. 使用@SpringBootApplication注解

許多Spring Boot開發人員總是使用@Configuration,@EnableAutoConfiguration和@ComponentScan來標注它們的主類。 由于這些注解經常一起使用(特別是如果您遵循之前說的最佳實踐),Spring Boot提供了一個方便的@SpringBootApplication注解作為這三個的替代方法。

@SpringBootApplication注解相當于使用@Configuration,@EnableAutoConfiguration和@ComponentScan和他們的默認屬性:

package com.example.myproject;

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

@SpringBootApplication // same as @Configuration @EnableAutoConfiguration @ComponentScan
public class Application {

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{SpringApplication.run(Application.class, args); }

}

@SpringBootApplication還提供了別名來定制@EnableAutoConfiguration和@ComponentScan的屬性。

19. 運行你的應用程序

將應用程序打包成jar并使用嵌入式HTTP服務器的最大優點之一就是可以按照你想用其他任何方式運行應用程序。調試Spring Boot應用程序也很容易; 您不需要任何專門的IDE插件或擴展。

本節僅涵蓋基于jar的打包,如果您選擇將應用程序打包為war文件,則應參考您的服務器和IDE的文檔。

19.1 從IDE運行

您可以從IDE中運行 Spring Boot 應用程序作為一個簡單的Java應用程序,但是首先需要導入項目。 導入步驟將根據您的IDE和構建系統而有所不同。 大多數IDE可以直接導入Maven項目,例如Eclipse用戶可以從File菜單中選擇import...→Existing Maven Projects。

如果您無法將項目直接導入到IDE中,則可以使用構建插件生成IDE元數據。 Maven包括Eclipse和IDEA的插件; Gradle為各種IDE提供插件。

如果您不小心運行了兩次Web應用程序,您將看到“Port already in use”中的錯誤。 使用STS用戶可以使用重新啟動按鈕而不是運行以確保任何現有實例已關閉。

19.2 作為已打包應用程序運行

如果您使用Spring Boot 的 Maven或Gradle插件創建可執行jar,則可以使用java -jar運行應用程序。 例如:

$ java -jar target/myproject-0.0.1-SNAPSHOT.jar

也可以啟用遠程調試支持運行打包的應用程序。 這允許您將調試器添加到打包的應用程序中:

$ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \-jar target/myproject-0.0.1-SNAPSHOT.jar

19.3 使用 Maven 插件

Spring Boot Maven 插件包含一個運行目標(goal ),可用于快速編譯和運行應用程序。 應用程序以exploded的形式運行,就像在IDE中一樣。

$ mvn spring-boot:run

您可能還需要使用一些有用的操作系統環境變量:

$ export MAVEN_OPTS=-Xmx1024m -XX:MaxPermSize=128M

19.4 使用Gradle插件

Spring Boot Gradlet插件還包括一個bootRun任務,可用于以exploded 形式運行應用程序。 每當導入spring-boot-gradle-plugin時,都會添加bootRun任務:

$ gradle bootRun

您可能還想使用這個有用的操作系統環境變量:

$ export JAVA_OPTS=-Xmx1024m -XX:MaxPermSize=128M

19.5 熱插拔

由于Spring Boot應用程序只是純Java應用程序,所以JVM熱插拔應該是開箱即用的。 JVM熱插拔在一定程度上受到可替代的字節碼的限制,更完整的解決方案,可以使用 JRebel 或者 Spring Loaded 項目。 spring-boot-devtools模塊還支持快速重新啟動應用程序。

有關詳細信息,請參閱第20章“開發人員工具”部分和熱插拔“操作方法”。

20. 開發工具

Spring Boot包括一組額外的工具,可以使應用程序開發體驗更加愉快。 spring-boot-devtools模塊可以包含在任何項目中,以提供額外的開發時功能。 要包含devtools支持,只需將模塊依賴關系添加到您的構建中:

Maven:

<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-devtools</artifactId><optional>true</optional></dependency> </dependencies>

Gradle:

dependencies {compile("org.springframework.boot:spring-boot-devtools") }

當運行完全打包的應用程序時,開發人員工具將自動禁用。 如果您的應用程序是使用java -jar啟動的,或者是使用特殊的類加載器啟動,那么它將會被認為是“生產環境的應用程序”。 將開發工具依賴關系標記為可選(optional)是一種最佳做法,可以防止使用項目將devtools傳遞性地應用于其他模塊。 Gradle不支持開箱即用的可選依賴項,因此您可能希望在此期間查看propdeps-plugin。

重新打包的jar包默認情況下不包含devtools。 如果要使用某些遠程devtools功能,您需要禁用excludeDevtools 構建下的屬性以包含devtools。 該屬性支持Maven和Gradle插件。

20.1 屬性默認值

Spring Boots支持的幾個庫使用緩存來提高性能。 例如,模板引擎將緩存編譯的模板,以避免重復解析模板文件。 此外,Spring MVC可以在返回靜態資源時向響應中添加HTTP緩存頭。

雖然緩存在生產中非常有益,但它在開發過程中可能會產生反效果,從而阻止您看到剛剛在應用程序中進行的更改。 因此,spring-boot-devtools將默認禁用這些緩存選項。

緩存選項通常由您的application.properties文件中的設置配置。 例如,Thymeleaf提供了spring.thymeleaf.cache屬性。 spring-boot-devtools模塊不需要手動設置這些屬性,而是自動應用更加合理的開發時(development-time)配置。

有關應用的屬性的完整列表,請參閱 DevToolsPropertyDefaultsPostProcessor。

20.2 自動重啟

使用spring-boot-devtools的應用程序將在類路徑上的文件發生更改時自動重新啟動。 這在IDE中開發時可能是一個有用的功能,因為它為代碼更改提供了非常快的反饋循環。 默認情況下,將監視指向文件夾的類路徑上的任何條目。 請注意,某些資源(如靜態資源和視圖模板)不需要重新啟動應用程序。

觸發重啟

當DevTools監視類路徑資源時,觸發重新啟動的唯一方法是更新類路徑中的文件時。 導致類路徑更新的方式取決于您正在使用的IDE。 在Eclipse中,保存修改的文件將導致類路徑被更新并觸發重新啟動。 在IntelliJ IDEA中,構建項目(Build→Make Project)將具有相同的效果。

只要 forking 被啟用,您也可以通過支持的構建插件(即Maven和Gradle)啟動應用程序,因為DevTools需要一個單獨的應用程序類加載器才能正常運行。Gradle和Maven默認情況下在類路徑上檢DevTools。

自動重啟當與LiveReload一起使用時工作非常好。 詳見下文。 如果您使用JRebel,自動重啟將被禁用,有利于動態類重新加載。 其他devtools功能仍然可以使用(如LiveReload和屬性覆蓋)。

DevTools依賴于應用程序上下文的關閉鉤子,以在重新啟動期間關閉它。 如果禁用了關閉掛鉤(SpringApplication.setRegisterShutdownHook(false)),DevTools將無法正常工作。

當判斷類路徑中的項目是否會在更改時觸發重新啟動時,DevTools會自動忽略名為spring-boot,spring-boot-devtools,spring-boot-autoconfigure,spring-boot-actuator和spring-boot-start的項目。

重新啟動(Restart) vs 重新加載(Reload)

Spring Boot提供的重新啟動技術使用兩個類加載器。 不會改的類(例如,來自第三方的jar)被加載到基類加載器中。 您正在開發的類被加載到重新啟動(restart)類加載器中。 當應用程序重新啟動時,重新啟動類加載器將被丟棄,并創建一個新的類加載器。 這種方法意味著應用程序重新啟動通常比“冷啟動”快得多,因為基類加載器已經可以使用。

如果發現重新啟動對應用程序不夠快,或遇到類加載問題,您可以考慮來自ZeroTurnaround的JRebel等重新加載技術。 這些工作通過在加載類時重寫(rewriting)類,使其更適合重新加載。 Spring Loaded提供了另一個選項,但是它在很多框架上不支持,并且不支持商用。

20.2.1 排除資源

在類路徑下,某些資源在更改時不一定需要觸發重新啟動。 例如,Thymeleaf模板可以直接編輯不需重啟。 默認情況下,有一些排除項,更改 /META-INF/maven,/META-INF/resources,/resources,/static,/public或/templates中的資源不會觸發重新啟動,但會觸發實時重新加載。 如果要自定義這些排除項,可以使用spring.devtools.restart.exclude屬性。 例如,要僅排除 /static和 /public,您可以設置:

spring.devtools.restart.exclude=static/**,public/**

如果要保留這些默認值并添加其他排除項,請改用spring.devtools.restart.additional-exclude屬性。

20.2.2 監視額外的路徑

有時當您對不在類路徑中的文件進行更改時,需要重新啟動或重新加載應用程序。為此,請使用spring.devtools.restart.additional-paths屬性來配置其他路徑以監視更改。 您可以使用[上述](described above)的spring.devtools.restart.exclude屬性來控制附加路徑下的更改是否會觸發完全重新啟動或只是實時重新加載。

20.2.3 禁用重啟

如果不想使用重新啟動功能,可以使用spring.devtools.restart.enabled屬性來禁用它。 在大多數情況下,您可以在application.properties中設置此項(這仍將初始化重新啟動類加載器,但不會監視文件更改)。

例如,如果您需要完全禁用重新啟動支持,因為它在一些特定庫中不能正常運行,則需要在調用SpringApplication.run(...)之前設置System屬性。 例如:

public static void main(String[] args) {System.setProperty("spring.devtools.restart.enabled", "false");SpringApplication.run(MyApp.class, args); }

20.2.4 使用觸發文件

如果您使用IDE工具編寫代碼,更改文件,則您可能希望僅在特定時間觸發重新啟動。 為此,您可以使用“觸發文件”,這是一個特殊文件,當您要實際觸發重新啟動檢查時,必須修改它。 更改文件只會觸發檢查,只有在Devtools檢測到它必須執行某些操作時才會重新啟動。 觸發文件可以手動更新,也可以通過IDE插件更新。

要使用觸發器文件,請使用spring.devtools.restart.trigger-file屬性。

您可能希望將spring.devtools.restart.trigger-file設置為全局設置,以使所有項目的行為方式相同。

20.2.5 自定義重新啟動類加載器

如上面的 Restart vs Reload 部分所述,重新啟動功能是通過使用兩個類加載器實現的。 對于大多數應用程序,此方法運行良好,但有時可能會導致類加載問題。

默認情況下,IDE中的任何打開的項目將使用“重新啟動”類加載器加載,任何常規.jar文件將使用“base”類加載器加載。 如果您在多模塊項目上工作,而不是每個模塊都導入到IDE中,則可能需要自定義事件。 為此,您可以創建一個META-INF / spring-devtools.properties文件。

spring-devtools.properties文件可以包含restart.exclude 和 restart.include.prefixed屬性。 include元素是應該被拉入“重新啟動(restart)”類加載器的項目,排除元素是應該向下推入“基本(base)”類加載器的項目。 屬性的值是將應用于類路徑的正則表達式模式。

例如:

restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar

所有屬性鍵必須是唯一的。 只要一個屬性從restart.include. 或restart.exclude. 開始,將被考慮。

將加載類路徑中的所有META-INF/spring-devtools.properties。 您可以在項目中打包文件,或者在項目所使用的庫中打包文件。

20.2.6 已知的限制

重新啟動功能對于使用標準ObjectInputStream反序列化的對象無效。 如果需要反序列化數據,可能需要使用Spring的ConfigurableObjectInputStream與Thread.currentThread()。getContextClassLoader()組合使用。

不幸的是,幾個第三方庫在不考慮上下文類加載器的情況下反序列化。 如果您發現這樣的問題,您需要向原始作者請求修復。

20.3 LiveReload

spring-boot-devtools模塊包括一個嵌入式LiveReload服務器,可以在資源更改時用于觸發瀏覽器刷新。 LiveReload瀏覽器擴展程序可以從 http://livereload.com 免費獲取Chrome,Firefox和Safari的插件。

如果您不想在應用程序運行時啟動LiveReload服務器,則可以將spring.devtools.livereload.enabled屬性設置為false。

一次只能運行一個LiveReload服務器。 開始應用程序之前,請確保沒有其他LiveReload服務器正在運行。 如果從IDE啟動多個應用程序,則只有第一個應用程序將支持LiveReload。

20.4 全局設置

您可以通過向 $HOME 文件夾添加名為.spring-boot-devtools.properties的文件來配置全局devtools設置(請注意文件名以“.”開頭)。 添加到此文件的任何屬性將適用于您的計算機上使用devtools的所有Spring Boot應用程序。 例如,要配置重新啟動以始終使用觸發器文件,您可以添加以下內容:

~/.spring-boot-devtools.properties.

spring.devtools.reload.trigger-file=.reloadtrigger

20.5遠程應用

Spring Boot開發工具不僅限于本地開發。 遠程運行應用程序時也可以使用多種功能。 遠程支持是可選擇的,要使其能夠確保重新打包的存檔中包含devtools:

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

那么你需要設置一個spring.devtools.remote.secret屬性,例如:

spring.devtools.remote.secret=mysecret

在遠程應用程序上啟用spring-boot-devtools是一種安全隱患。 您不應該在生產部署中啟用該支持。

遠程devtools支持分為兩部分: 有一個接受連接的服務器端和您在IDE中運行的客戶端應用程序。 當spring.devtools.remote.secret屬性設置時,服務器組件將自動啟用。 客戶端組件必須手動啟動。

20.5.1 運行遠程客戶端應用程序

遠程客戶端應用程序旨在從IDE中運行。 您需要使用與要連接的遠程項目相同的類路徑運行org.springframework.boot.devtools.RemoteSpringApplication。 傳遞給應用程序的必選參數應該是您要連接到的遠程URL。

例如,如果您使用Eclipse或STS,并且有一個名為my-app的項目已部署到Cloud Foundry,則可以執行以下操作:

  • 從Run 菜單中選擇Run Configurations…。
  • 創建一個新的Java Application “launch configuration”。
  • 瀏覽my-app項目。
  • 使用org.springframework.boot.devtools.RemoteSpringApplication作為主類。
  • 將https://myapp.cfapps.io添加到程序參數(或任何遠程URL)中。

運行的遠程客戶端將如下所示:

. ____ _ __ _ _/\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \ ( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \\\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) )' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / /=========|_|==============|___/===================================/_/_/_/:: Spring Boot Remote :: 1.5.2.RELEASE

2015-06-10 18:25:06.632 INFO 14938 — [ main] o.s.b.devtools.RemoteSpringApplication : Starting RemoteSpringApplication on pwmbp with PID 14938 (/Users/pwebb/projects/spring-boot/code/spring-boot-devtools/target/classes started by pwebb in /Users/pwebb/projects/spring-boot/code/spring-boot-samples/spring-boot-sample-devtools)
2015-06-10 18:25:06.671 INFO 14938 — [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@2a17b7b6: startup date [Wed Jun 10 18:25:06 PDT 2015]; root of context hierarchy
2015-06-10 18:25:07.043 WARN 14938 — [ main] o.s.b.d.r.c.RemoteClientConfiguration : The connection to http://localhost:8080 is insecure. You should use a URL starting with ‘https://’.
2015-06-10 18:25:07.074 INFO 14938 — [ main] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2015-06-10 18:25:07.130 INFO 14938 — [ main] o.s.b.devtools.RemoteSpringApplication : Started RemoteSpringApplication in 0.74 seconds (JVM running for 1.105)

由于遠程客戶端正在使用與實際應用程序相同的類路徑,因此可以直接讀取應用程序屬性。 這是spring.devtools.remote.secret屬性如何讀取并傳遞到服務器進行身份驗證。

建議使用https//作為連接協議,以便流量被加密,防止密碼被攔截。

如果需要使用代理訪問遠程應用程序,請配置spring.devtools.remote.proxy.host和spring.devtools.remote.proxy.port屬性。

20.5.2 遠程更新

遠程客戶端將以與本地相同的方式監視應用程序類路徑的更改。 任何更新的資源將被推送到遠程應用程序,并且(如果需要的話)觸發重新啟動。 如果您正在迭代使用您當地沒有的云服務的功能,這可能會非常有用。 通常,遠程更新和重新啟動比完全重建和部署周期要快得多。

僅在遠程客戶端運行時才監視文件。 如果在啟動遠程客戶端之前更改文件,則不會將其推送到遠程服務器。

20.5.3 遠程調試隧道

在遠程應用程序診斷問題時,Java遠程調試非常有用。 不幸的是,當您的應用程序部署在數據中心之外時,并不總是能夠進行遠程調試。 如果您正在使用基于容器的技術(如Docker),遠程調試也可能難以設置。

為了幫助解決這些限制,devtools支持基于HTTP隧道的傳輸遠程調試傳輸。 遠程客戶端在端口8000上提供本地服務器,您可以連接遠程調試器。 建立連接后,通過HTTP將調試數據發送到遠程應用程序。 如果要使用其他端口,可以使用spring.devtools.remote.debug.local-port屬性更改。

您需要確保遠程應用程序啟用遠程調試啟用。 通常可以通過配置JAVA_OPTS來實現。 例如,使用Cloud Foundry,您可以將以下內容添加到manifest.yml中:

---env:JAVA_OPTS: "-Xdebug -Xrunjdwp:server=y,transport=dt_socket,suspend=n"

請注意,您不需要將 address=NNNN 選項傳遞給-Xrunjdwp。 如果省略Java將隨機選擇一個的空閑端口。

通過網絡調試遠程服務可能很慢,您可能需要在IDE中增加超時時間。 例如,在Eclipse中,您可以從Preferences...中選擇Java→Debug ,并將Debugger timeout (ms)更改為更合適的值(大多數情況下,60000可以正常工作)。

當使用IntelliJ IDEA的遠程調試隧道時,必須將所有調試斷點配置為掛起線程而不是掛起VM。 默認情況下,IntelliJ IDEA中的斷點會掛起整個VM,而不是僅掛起觸發斷點的線程。 這會導致掛起管理遠程調試通道的線程等不必要的副作用,導致調試會話凍結。 當使用IntelliJ IDEA的遠程調試隧道時,應將所有斷點配置為掛起線程而不是VM。 有關詳細信息,請參閱IDEA-165769。

21. 包裝您的應用程序到生產環境

可執行的jar可用于生產部署。 由于它們是相互獨立的,它們也非常適合基于云的部署。

對于其他“生產環境準備”功能,如健康,審計和metric REST或JMX端點; 考慮添加spring-boot-actuator。 有關詳細信息,請參見第V部分“Spring Boot Actuator:生產環境準備功能”。

22. 接下來應該讀什么

您現在應該很好地了解如何使用Spring Boot以及您應該遵循的一些最佳做法。 您現在可以深入了解特定的Spring Boot功能,或者您可以跳過這部分,真的閱讀Spring Boot的“生產環境準備”方面。

Part IV. Spring Boot 功能

本節將會介紹Spring Boot的一些細節。 在這里,您可以了解您將要使用和自定義的主要功能。 如果還沒有準備好,您可能需要閱讀第二部分“入門指南”和第三部分“使用 Spring Boot”部分,以使您有基礎的良好基礎。

23. SpringApplication

SpringApplication類提供了一種方便的方法來引導將從main()方法啟動的Spring應用程序。 在許多情況下,您只需委派靜態SpringApplication.run()方法:

public static void main(String[] args) {SpringApplication.run(MySpringConfiguration.class, args); }

當您的應用程序啟動時,您應該看到類似于以下內容:

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

2013-07-31 00:08:16.117 INFO 56603 — [ main] o.s.b.s.app.SampleApplication : Starting SampleApplication v0.1.0 on mycomputer with PID 56603 (/apps/myapp.jar started by pwebb)
2013-07-31 00:08:16.166 INFO 56603 — [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@6e5a8246: startup date [Wed Jul 31 00:08:16 PDT 2013]; root of context hierarchy
2014-03-04 13:09:54.912 INFO 41370 — [ main] .t.TomcatEmbeddedServletContainerFactory : Server initialized with port: 8080
2014-03-04 13:09:56.501 INFO 41370 — [ main] o.s.b.s.app.SampleApplication : Started SampleApplication in 2.992 seconds (JVM running for 3.658)

默認情況下,將顯示INFO 級別log消息,包括用戶啟動應用程序一些相關的啟動細節。

23.1 啟動失敗

如果您的應用程序無法啟動,則注冊的FailureAnalyzers會提供專門的錯誤消息和具體操作來解決問題。 例如,如果您在端口8080上啟動Web應用程序,并且該端口已在使用中,則應該會看到類似于以下內容的內容:

*************************** APPLICATION FAILED TO START ***************************

Description:

Embedded servlet container failed to start. Port 8080 was already in use.

Action:

Identify and stop the process that’s listening on port 8080 or configure this application to listen on another port.

Spring Boot提供了眾多的FailureAnalyzer實現,您可以非常容易地添加自己的實現。

如果沒有故障分析器(analyzers)能夠處理異常,您仍然可以顯示完整的自動配置報告,以更好地了解出現的問題。 為此,您需要啟用debug屬性或啟用org.springframework.boot.autoconfigure.logging.AutoConfigurationReportLoggingInitializer的DEBUG日志。

例如,如果使用java -jar運行應用程序,則可以按如下方式啟用 debug:

$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug

23.2 自定義Banner

可以通過在您的類路徑中添加一個 banner.txt 文件,或者將banner.location設置到banner文件的位置來更改啟動時打印的banner。 如果文件有一些不常用的編碼,你可以設置banner.charset(默認為UTF-8)。除了文本文件,您還可以將banner.gif,banner.jpg或banner.png圖像文件添加到您的類路徑中,或者設置一個banner.image.location屬性。 圖像將被轉換成ASCII藝術表現,并打印在任何文字banner上方。

您可以在banner.txt文件中使用以下占位符:

表23.1. banner變量

變量名描述
${application.version}在MANIFEST.MF中聲明的應用程序的版本號。例如, Implementation-Version: 1.0 被打印為 1.0.
${application.formatted-version}在MANIFEST.MF中聲明的應用程序版本號的格式化顯示(用括號括起來,以v為前綴)。 例如 (v1.0)。
${spring-boot.version}您正在使用的Spring Boot版本。 例如1.5.2.RELEASE。
${spring-boot.formatted-version}您正在使用格式化顯示的Spring Boot版本(用括號括起來,以v為前綴)。 例如(v1.5.2.RELEASE)。
${Ansi.NAME} (or ${AnsiColor.NAME}, ${AnsiBackground.NAME}, ${AnsiStyle.NAME})其中NAME是ANSI轉義碼的名稱。 有關詳細信息,請參閱 AnsiPropertySource。
${application.title}您的應用程序的標題在MANIFEST.MF中聲明。 例如Implementation-Title:MyApp打印為MyApp。

如果要以編程方式生成banner,則可以使用SpringApplication.setBanner()方法。 使用org.springframework.boot.Banner 如接口,并實現自己的printBanner() 方法。

您還可以使用spring.main.banner-mode屬性來決定是否必須在System.out(控制臺)上打印banner,使用配置的logger(log)或不打印(off)。

23.3 定制SpringApplication

如果SpringApplication默認值不符合您的想法,您可以創建本地實例并進行自定義。 例如,關閉banner:

public static void main(String[] args) {SpringApplication app = new SpringApplication(MySpringConfiguration.class);app.setBannerMode(Banner.Mode.OFF);app.run(args); }

傳遞給SpringApplication的構造函數參數是spring bean的配置源。 在大多數情況下,這些將引用@Configuration類,但它們也可以引用XML配置或應掃描的包。

也可以使用application.properties文件配置SpringApplication。 有關詳細信息,請參見第24章“外部配置”。

有關配置選項的完整列表,請參閱SpringApplication Javadoc。

23.4 流式構建 API

如果您需要構建一個ApplicationContext層次結構(具有父/子關系的多個上下文),或者如果您只想使用“流式(fluent)”構建器API,則可以使用SpringApplicationBuilder。

SpringApplicationBuilder允許您鏈式調用多個方法,并包括允許您創建層次結構的父和子方法。

例如:

new SpringApplicationBuilder().sources(Parent.class).child(Application.class).bannerMode(Banner.Mode.OFF).run(args);

創建ApplicationContext層次結構時有一些限制,例如 Web組件必須包含在子上下文中,并且相同的環境將用于父和子上下文。 有關詳細信息,請參閱SpringApplicationBuilder Javadoc。

23.5 Application events and listeners

除了常見的Spring Framework事件(如 ContextRefreshedEvent)之外,SpringApplication還會發送一些其他應用程序事件。

在創建ApplicationContext之前,實際上觸發了一些事件,因此您不能在@Bean上注冊一個監聽器。 您可以通過SpringApplication.addListeners(...) 或SpringApplicationBuilder.listeners(...)方法注冊它們。

如果您希望自動注冊這些偵聽器,無論創建應用程序的方式如何,都可以將META-INF / spring.factories文件添加到項目中,并使用org.springframework.context.ApplicationListener引用您的偵聽器。 org.springframework.context.ApplicationListener=com.example.project.MyListener

當您的應用程序運行時,事件按照以下順序發送:

  • ApplicationStartingEvent在運行開始時發送,但在注冊偵聽器和注冊初始化器之后。
  • 當已經知道要使用的上下文(context)環境,并在context創建之前,將發送ApplicationEnvironmentPreparedEvent。
  • ApplicationPreparedEvent在啟動刷新(refresh)之前發送,但在加載了bean定義之后。
  • ApplicationReadyEvent在刷新之后被發送,并且處理了任何相關的回調以指示應用程序準備好服務請求。
  • 如果啟動時發生異常,則發送ApplicationFailedEvent。
  • 一般您不需要使用應用程序事件,但可以方便地知道它們存在。 在內部,Spring Boot使用事件來處理各種任務。

    23.6 Web 環境

    SpringApplication將嘗試代表您創建正確類型的ApplicationContext。 默認情況下,將使用AnnotationConfigApplicationContext或AnnotationConfigEmbeddedWebApplicationContext,具體取決于您是否正在開發Web應用程序。

    用于確定“Web環境”的算法是相當簡單的(基于幾個類的存在)。 如果需要覆蓋默認值,可以使用setWebEnvironment(boolean webEnvironment)。

    也可以通過調用setApplicationContextClass() 對ApplicationContext完全控制。

    在JUnit測試中使用SpringApplication時,通常需要調用setWebEnvironment()

    23.7 訪問應用程序參數

    如果您需要訪問傳遞給SpringApplication.run()的應用程序參數,則可以注入org.springframework.boot.ApplicationArguments bean。 ApplicationArguments接口提供對原始String []參數以及解析選項和非選項參數的訪問:

    import org.springframework.boot.* import org.springframework.beans.factory.annotation.* import org.springframework.stereotype.*

    @Component
    public class MyBean {

    <span class="hljs-meta">@Autowired</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">MyBean</span><span class="hljs-params">(ApplicationArguments args)</span> </span>{<span class="hljs-keyword">boolean</span> debug = args.containsOption(<span class="hljs-string">"debug"</span>);List&lt;String&gt; files = args.getNonOptionArgs();<span class="hljs-comment">// if run with "--debug logfile.txt" debug=true, files=["logfile.txt"]</span> }

    }

    Spring Boot還將向Spring Environment 注冊一個CommandLinePropertySource。 這允許您也使用@Value注解注入應用程序參數。

    23.8 使用ApplicationRunner或CommandLineRunner

    SpringApplication啟動時如果您需要運行一些特定的代碼,就可以實現ApplicationRunner或CommandLineRunner接口。 兩個接口都以相同的方式工作,并提供一個單獨的運行方法,這將在SpringApplication.run(...)完成之前調用。

    CommandLineRunner接口提供對應用程序參數的訪問(簡單的字符串數組),而ApplicationRunner使用上述的ApplicationArguments接口。

    @Component public class MyBean implements CommandLineRunner { <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">(String... args)</span> </span>{<span class="hljs-comment">// Do something...</span> }

    }

    如果定義了若干CommandLineRunner或ApplicationRunner bean,這些bean必須按特定順序調用,您可以實現org.springframework.core.Ordered接口,也可以使用org.springframework.core.annotation.Order注解。

    23.9 Application exit

    每個SpringApplication將注冊一個JVM關閉鉤子,以確保ApplicationContext在退出時正常關閉。 可以使用所有標準的Spring生命周期回調(例如DisposableBean接口或@PreDestroy注釋)。

    另外,如果希望在應用程序結束時返回特定的退出代碼,那么bean可以實現org.springframework.boot.ExitCodeGenerator接口。

    23.10 管理功能

    可以通過指定spring.application.admin.enabled屬性來為應用程序啟用與管理相關的功能。 這會在平臺MBeanServer上暴露SpringApplicationAdminMXBean。 您可以使用此功能來遠程管理您的Spring Boot應用程序。 這對于任何服務包裝器(service wrapper)實現也是有用的。

    如果您想知道應用程序在哪個HTTP端口上運行,請使用local.server.port鍵獲取該屬性。

    啟用此功能時請小心,因為MBean公開了關閉應用程序的方法。

    24. 外部配置

    Spring Boot允許您外部化您的配置,以便您可以在不同的環境中使用相同的應用程序代碼。 您可以使用properties文件,YAML文件,環境變量和命令行參數來外部化配置。 可以使用@Value注釋將屬性值直接注入到您的bean中,該注釋可通過Spring環境(Environment)抽象訪問,或通過@ConfigurationProperties綁定到結構化對象。

    Spring Boot使用非常特別的PropertySource命令,旨在允許合理地覆蓋值。屬性按以下順序選擇:

  • 在您的HOME目錄設置的Devtools全局屬性(~/.spring-boot-devtools.properties)。
  • 單元測試中的 @TestPropertySource 注解。
  • 單元測試中的 @SpringBootTest#properties 注解屬性
  • 命令行參數。
  • SPRING_APPLICATION_JSON 中的屬性值(內嵌JSON嵌入到環境變量或系統屬性中)。
  • ServletConfig 初始化參數。
  • ServletContext 初始化參數。
  • 來自 java:comp/env 的JNDI屬性。
  • Java系統屬性(System.getProperties())。
  • 操作系統環境變量。
  • RandomValuePropertySource,只有隨機的屬性 random.* 中。
  • jar包外面的 Profile-specific application properties (application- {profile} .properties和YAML變體)
  • jar包內的 Profile-specific application properties (application-{profile}.properties和YAML變體)
  • jar包外的應用屬性文件(application.properties和YAML變體)。
  • jar包內的應用屬性文件(application.properties和YAML變體)。
  • 在@Configuration上的@PropertySource注解。
  • 默認屬性(使用SpringApplication.setDefaultProperties設置)。
  • 一個具體的例子,假設你開發一個使用name屬性的@Component:

    import org.springframework.stereotype.* import org.springframework.beans.factory.annotation.*

    @Component
    public class MyBean {

    <span class="hljs-meta">@Value</span>(<span class="hljs-string">"${name}"</span>) <span class="hljs-keyword">private</span> String name;<span class="hljs-comment">// ...</span>

    }

    在應用程序類路徑(例如,您的jar中)中,您可以擁有一個application.properties,它為 name 屬性提供了默認屬性值。 在新環境中運行時,可以在您的jar外部提供一個application.properties來覆蓋 name 屬性; 對于一次性測試,您可以使用特定的命令行開關啟動(例如,java -jar app.jar --name="Spring")。

    SPRING_APPLICATION_JSON屬性可以在命令行中提供一個環境變量。 例如在UN*X shell中:

    $ SPRING_APPLICATION_JSON='{"foo":{"bar":"spam"}}' java -jar myapp.jar

    在本例中,您將在Spring環境中使用foo.bar = spam。 您也可以在系統變量中將JSON作為spring.application.json提供:

    $ java -Dspring.application.json='{"foo":"bar"}' -jar myapp.jar

    或命令行參數:

    $ java -jar myapp.jar --spring.application.json='{"foo":"bar"}'

    或作為JNDI變量 java:comp/env/spring.application.json 。

    24.1 配置隨機值

    RandomValuePropertySource可用于注入隨機值(例如,進入秘密或測試用例)。 它可以產生整數,長整數,uuid或字符串,例如

    my.secret=${random.value} my.number=${random.int} my.bignumber=${random.long} my.uuid=${random.uuid} my.number.less.than.ten=${random.int(10)} my.number.in.range=${random.int[1024,65536]}

    random.int *語法是 OPEN value (,max) CLOSE ,其中OPEN,CLOSE是任何字符和值,max是整數。 如果提供max,則值為最小值,max為最大值(獨占)。

    24.2 訪問命令行屬性

    默認情況下,SpringApplication將任何命令行選項參數(以'-- '開頭,例如--server.port=9000)轉換為屬性,并將其添加到Spring環境中。 如上所述,命令行屬性始終優先于其他屬性來源。

    如果不希望將命令行屬性添加到環境中,可以使用SpringApplication.setAddCommandLineProperties(false)禁用它們。

    24.3 應用程序屬性文件

    SpringApplication將從以下位置的application.properties文件中加載屬性,并將它們添加到Spring Environment中:

  • 當前目錄的/config子目錄
  • 當前目錄
  • classpath中/config包
  • classpath root路徑
  • 該列表按優先級從高到低排序。

    也可以使用YAML('.yml')文件替代“.properties”。

    如果您不喜歡application.properties作為配置文件名,可以通過指定一個spring.config.name Spring environment屬性來切換到另一個。 您還可以使用spring.config.location環境屬性(用逗號分隔的目錄位置列表或文件路徑)顯式引用位置。

    $ java -jar myproject.jar --spring.config.name=myproject

    $ java -jar myproject.jar --spring.config.location=classpath:/default.properties,classpath:/override.properties

    spring.config.name和spring.config.location一開始就被用于確定哪些文件必須被加載,因此必須將它們定義為環境屬性(通常是OS env,system屬性或命令行參數)。

    如果spring.config.location包含的如果是目錄而非文件,那么它們應該以/結尾(并將在加載之前附加從spring.config.name生成的名稱,包括profile-specific的文件名)。 在spring.config.location中指定的文件按原樣使用,不支持特定于配置文件的變體,并且將被任何特定于配置文件的屬性覆蓋。

    默認的搜索路徑 classpath:,classpath:/config,file:,file:config/ 始終會被搜索,不管spring.config.location的值如何。 該搜索路徑從優先級排序從低到高(file:config/最高)。 如果您指定自己的位置,則它們優先于所有默認位置,并使用相同的從最低到最高優先級排序。 這樣,您可以在application.properties(或使用spring.config.name選擇的任何其他基礎名稱)中為應用程序設置默認值,并在運行時使用不同的文件覆蓋它,并保留默認值。

    如果您使用環境(environment)變量而不是系統屬性,大多數操作系統不允許使用句點分隔(period-separated)的鍵名稱,但可以使用下劃線(例如,SPRING_CONFIG_NAME,而不是spring.config.name)

    如果您運行在容器中,則可以使用JNDI屬性(在 java:comp/env 中)或servlet上下文初始化參數,而不是環境變量或系統屬性。

    24.4 指定配置(Profile-specific)的屬性

    除了application.properties文件外,還可以使用命名約定application- {profile}.properties定義的指定配置文件。 環境具有一組默認配置文件,如果沒有設置活動配置文件(即,如果沒有顯式激活配置文件,則加載了來自application-default.properties的屬性)。

    指定配置文件(Profile-specific)的屬性從與標準application.properties相同的位置加載,指定配置( profile-specific)文件始終覆蓋非指定文件,而不管指定配置文件是否在打包的jar內部或外部。

    如果有幾個指定配置文件,則應用最后一個配置。 例如,由spring.profiles.active屬性指定的配置文件在通過SpringApplication API配置的配置之后添加,因此優先級高。

    如果您在spring.config.location中指定了任何文件,則不會考慮這些特定配置(profile-specific)文件的變體。 如果您還想使用指定配置(profile-specific)文件的屬性,請使用spring.config.location中的目錄。

    24.5 properties 文件中的占位符

    application.properties中的值在使用時通過已有的環境進行過濾,以便您可以引用之前定義的值(例如,從系統屬性)。

    app.name=MyApp app.description=${app.name} is a Spring Boot application

    您也可以使用此技術創建現有Spring Boot屬性的“簡寫“。 有關詳細信息,請參見第72.4節“使用”短命令行參數“how-to”。

    24.6 使用YAML替代 Properties

    YAML是JSON的超集,因此這是分層配置數據一種非常方便的格式,。 每當您的類路徑中都有SnakeYAML庫時,SpringApplication類將自動支持YAML作為 properties 的替代方法。

    如果您使用“Starters”,SnakeYAML將通過spring-boot-starter自動提供。

    24.6.1 加載 YAML

    Spring Framework提供了兩個方便的類,可用于加載YAML文檔。 YamlPropertiesFactoryBean將YAML作為Properties加載,YamlMapFactoryBean將YAML作為Map加載。

    例如,下面YAML文檔:

    environments:dev:url: http://dev.bar.comname: Developer Setupprod:url: http://foo.bar.comname: My Cool App

    將轉化為屬性:

    environments.dev.url=http://dev.bar.com environments.dev.name=Developer Setup environments.prod.url=http://foo.bar.com environments.prod.name=My Cool App

    YAML列表表示為具有[index] dereferencers的屬性鍵,例如YAML:

    my:servers:- dev.bar.com- foo.bar.com

    將轉化為屬性:

    my.servers[0]=dev.bar.com my.servers[1]=foo.bar.com

    要使用Spring DataBinder工具(@ConfigurationProperties做的)綁定到這樣的屬性,您需要有一個屬性類型為java.util.List(或Set)的目標bean,并且您需要提供一個setter,或者 用可變值初始化它,例如 這將綁定到上面的屬性

    @ConfigurationProperties(prefix="my") public class Config { <span class="hljs-keyword">private</span> List&lt;String&gt; servers = <span class="hljs-keyword">new</span> ArrayList&lt;String&gt;();<span class="hljs-function"><span class="hljs-keyword">public</span> List&lt;String&gt; <span class="hljs-title">getServers</span><span class="hljs-params">()</span> </span>{<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.servers; }

    }

    24.6.2 將YAML作為Spring環境中的屬性文件

    可以使用YamlPropertySourceLoader類在Spring環境中將YAML作為PropertySource暴露出來。 這允許您使用熟悉的@Value注解和占位符語法來訪問YAML屬性。

    24.6.3 多個YAML文件

    您可以使用spring.profiles鍵指定單個文件中的多個特定配置文件YAML文檔,以指示文檔何時應用。 例如:

    server:address: 192.168.1.100 --- spring:profiles: development server:address: 127.0.0.1 --- spring:profiles: production server:address: 192.168.1.120

    在上面的示例中,如果開發配置文件處于活動狀態,則server.address屬性將為127.0.0.1。 如果開發和生產配置文件未啟用,則該屬性的值將為192.168.1.100。

    如果應用程序上下文啟動時沒有顯式激活,默認配置文件將被激活。 所以在這個YAML中,我們為security.user.password設置一個僅在“默認”配置文件中可用的值:

    server:port: 8000 --- spring:profiles: default security:user:password: weak

    使用“spring.profiles”元素指定的Spring profiles 以選擇使用! 字符。 如果為單個文檔指定了否定和非否定的配置文件,則至少有一個非否定配置文件必須匹配,沒有否定配置文件可能匹配。

    24.6.4 YAML的缺點

    YAML文件無法通過@PropertySource注解加載。 因此,在需要以這種方式加載值的情況下,需要使用properties文件。

    24.6.5 合并YAML列表

    如上所述,任何YAML內容最終都會轉換為屬性。 當通過配置文件覆蓋“列表”屬性時,該過程可能比較直觀。

    例如,假設名稱和描述屬性默認為空的MyPojo對象。 讓我們從FooProperties中公開MyPojo的列表:

    @ConfigurationProperties("foo") public class FooProperties { private final List&lt;MyPojo&gt; list = new ArrayList&lt;&gt;();public List&lt;MyPojo&gt; getList() {return this.list; }

    }

    類比以下配置:

    foo:list:- name: my namedescription: my description --- spring:profiles: dev foo:list:- name: my another name

    如果dev配置沒有激活,FooProperties.list將包含一個如上定義的MyPojo條目。 如果啟用了配置文件,列表仍將包含一個條目(名稱為“my another name”,description=null)。 此配置不會將第二個MyPojo實例添加到列表中,并且不會將項目合并。

    當在多個配置文件中指定集合時,使用具有最高優先級的集合(并且僅使用該配置文件):

    foo:list:- name: my namedescription: my description- name: another namedescription: another description --- spring:profiles: dev foo:list:- name: my another name

    在上面的示例中,考慮到dev配置文件處于激活狀態,FooProperties.list將包含一個MyPojo條目(名稱為“my another name”和description=null)。

    24.7 類型安全的配置屬性

    使用@Value(“${property}”)注釋來注入配置屬性有時可能很麻煩,特別是如果您正在使用多個層次結構的屬性或數據時。 Spring Boot提供了一種處理屬性的替代方法,允許強類型Bean管理并驗證應用程序的配置。

    package com.example;

    import java.net.InetAddress;
    import java.util.ArrayList;
    import java.util.Collections;
    import java.util.List;

    import org.springframework.boot.context.properties.ConfigurationProperties;

    @ConfigurationProperties(“foo”)
    public class FooProperties {

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">boolean</span> enabled;<span class="hljs-keyword">private</span> InetAddress remoteAddress;<span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Security security = <span class="hljs-keyword">new</span> Security();<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">boolean</span> <span class="hljs-title">isEnabled</span><span class="hljs-params">()</span> </span>{ ... }<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setEnabled</span><span class="hljs-params">(<span class="hljs-keyword">boolean</span> enabled)</span> </span>{ ... }<span class="hljs-function"><span class="hljs-keyword">public</span> InetAddress <span class="hljs-title">getRemoteAddress</span><span class="hljs-params">()</span> </span>{ ... }<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setRemoteAddress</span><span class="hljs-params">(InetAddress remoteAddress)</span> </span>{ ... }<span class="hljs-function"><span class="hljs-keyword">public</span> Security <span class="hljs-title">getSecurity</span><span class="hljs-params">()</span> </span>{ ... }<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Security</span> </span>{<span class="hljs-keyword">private</span> String username;<span class="hljs-keyword">private</span> String password;<span class="hljs-keyword">private</span> List&lt;String&gt; roles = <span class="hljs-keyword">new</span> ArrayList&lt;&gt;(Collections.singleton(<span class="hljs-string">"USER"</span>));<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getUsername</span><span class="hljs-params">()</span> </span>{ ... }<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setUsername</span><span class="hljs-params">(String username)</span> </span>{ ... }<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getPassword</span><span class="hljs-params">()</span> </span>{ ... }<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setPassword</span><span class="hljs-params">(String password)</span> </span>{ ... }<span class="hljs-function"><span class="hljs-keyword">public</span> List&lt;String&gt; <span class="hljs-title">getRoles</span><span class="hljs-params">()</span> </span>{ ... }<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setRoles</span><span class="hljs-params">(List&lt;String&gt; roles)</span> </span>{ ... }}

    }

    上述POJO定義了以下屬性:

    • foo.enabled,默認為false
    • foo.remote-address,具有可以從String強轉的類型
    • foo.security.username,具有內置的“安全性(security)”,其名稱由屬性名稱決定。 特別是返回類型并沒有被使用,可能是SecurityProperties
    • foo.security.password
    • foo.security.roles,一個String集合

    Getters和setter方法通常是必須要有的,因為綁定是通過標準的Java Beans屬性描述符,就像在Spring MVC中一樣。 在某些情況下可能會省略setter方法:

    • Map 只要它們被初始化,需要一個getter,但不一定是一個setter,因為它們可以被binder修改。
    • 集合和數組可以通過索引(通常使用YAML)或使用單個逗號分隔值(Properties中)來訪問。 在后一種情況下,setter方法是強制性的。 我們建議總是為這樣的類型添加一個設置器。 如果您初始化集合,請確保它不是不可變的(如上例所示)
    • 如果已初始化嵌套POJO屬性(如上例中的Security字段),則不需要setter方法。如果您希望binder使用其默認構造函數即時創建實例,則需要一個setter。

    有些人使用Project Lombok自動添加getter和setter。 確保Lombok不會為這種類型生成任何特定的構造函數,因為構造函將被容器自動用于實例化對象。

    另請參閱@Value和@ConfigurationProperties之間的不同。

    您還需要列出在@EnableConfigurationProperties注解中注冊的屬性類:

    @Configuration @EnableConfigurationProperties(FooProperties.class) public class MyConfiguration { }

    當@ConfigurationProperties bean以這種方式注冊時,該bean將具有常規名稱:<prefix> - <fqn>,其中<prefix>是@ConfigurationProperties注解中指定的環境密鑰前綴,<fqn>是bean的全名(fully qualified name)。 如果注解不提供任何前綴,則僅使用該bean的全名。上面示例中的bean名稱將是foo-com.example.FooProperties。

    即使上述配置將為FooProperties創建一個常規bean,我們建議@ConfigurationProperties僅處理環境,特別是不從上下文中注入其他bean。 話雖如此,@EnableConfigurationProperties注釋也會自動應用于您的項目,以便使用@ConfigurationProperties注釋的任何現有的bean都將從環境配置。 您可以通過確保FooProperties已經是一個bean來快速上面的MyConfiguration

    @Component @ConfigurationProperties(prefix="foo") public class FooProperties { <span class="hljs-comment">// ... see above</span>

    }

    這種配置方式與SpringApplication外部的YAML配置相當:

    # application.yml

    foo:
    remote-address: 192.168.1.1
    security:
    username: foo
    roles:
    - USER
    - ADMIN

    #
    additional configuration as required

    要使用@ConfigurationProperties bean,您可以像其他任何bean一樣注入它們。

    @Service public class MyService { <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> FooProperties properties;<span class="hljs-meta">@Autowired</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">MyService</span><span class="hljs-params">(FooProperties properties)</span> </span>{<span class="hljs-keyword">this</span>.properties = properties; }<span class="hljs-comment">//...</span><span class="hljs-meta">@PostConstruct</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">openConnection</span><span class="hljs-params">()</span> </span>{Server server = <span class="hljs-keyword">new</span> Server(<span class="hljs-keyword">this</span>.properties.getRemoteAddress());<span class="hljs-comment">// ...</span> }

    }

    使用@ConfigurationProperties還可以生成IDE可以為自己的密鑰提供自動完成的元數據文件,有關詳細信息,請參見附錄B,配置元數據附錄。

    24.7.1第三方配置

    除了使用@ConfigurationProperties來注解類,還可以在public @Bean方法中使用它。 當您希望將屬性綁定到不受控制的第三方組件時,這可能特別有用。

    @ConfigurationProperties(prefix = "bar") @Bean public BarComponent barComponent() {... }

    使用 bar 前綴定義的任何屬性將以與上述FooProperties示例類似的方式映射到該BarComponent bean。

    24.7.2 寬松的綁定

    Spring Boot使用一些寬松的規則將環境屬性綁定到@ConfigurationProperties bean,因此不需要在Environment屬性名稱和bean屬性名稱之間進行完全匹配。 常用的例子是這樣有用的:虛分離(例如上下文路徑綁定到contextPath)和大寫(例如PORT綁定到端口)環境屬性。

    例如,給定以下@ConfigurationProperties類:

    @ConfigurationProperties(prefix="person") public class OwnerProperties { <span class="hljs-keyword">private</span> String firstName;<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getFirstName</span><span class="hljs-params">()</span> </span>{<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.firstName; }<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">setFirstName</span><span class="hljs-params">(String firstName)</span> </span>{<span class="hljs-keyword">this</span>.firstName = firstName; }

    }

    可以使用以下屬性名稱:

    表格 24.1. relaxed binding

    PropertyNote
    person.firstName標準駱峰命名法。
    person.first-name虛線符號,推薦用于.properties和.yml文件。
    person.first_name下劃線符號,用于.properties和.yml文件的替代格式。
    PERSON_FIRST_NAME大寫格式 推薦使用系統環境變量時。

    24.7.3屬性轉換

    當Spring綁定到@ConfigurationProperties bean時,Spring將嘗試將外部應用程序屬性強制為正確的類型。 如果需要自定義類型轉換,您可以提供ConversionService bean(使用bean id conversionService)或自定義屬性編輯器(通過CustomEditorConfigurer bean)或自定義轉換器(使用注釋為@ConfigurationPropertiesBinding的bean定義)。

    由于在應用程序生命周期期間非常早請求此Bean,請確保限制ConversionService正在使用的依賴關系。 通常,您需要的任何依賴關系可能無法在創建時完全初始化。 如果配置密鑰強制不需要,只需依賴使用@ConfigurationPropertiesBinding限定的自定義轉換器,就可以重命名自定義ConversionService。

    24.7.4 @ConfigurationProperties驗證

    當Spring的@Validated注釋解時,Spring Boot將嘗試驗證@ConfigurationProperties類。 您可以直接在配置類上使用JSR-303 javax.validation約束注釋。 只需確保您的類路徑中符合JSR-303實現,然后在您的字段中添加約束注釋:

    @ConfigurationProperties(prefix="foo") @Validated public class FooProperties { <span class="hljs-meta">@NotNull</span> <span class="hljs-keyword">private</span> InetAddress remoteAddress;<span class="hljs-comment">// ... getters and setters</span>

    }

    為了驗證嵌套屬性的值,您必須將關聯字段注釋為@Valid以觸發其驗證。 例如,基于上述FooProperties示例:

    @ConfigurationProperties(prefix="connection") @Validated public class FooProperties { <span class="hljs-meta">@NotNull</span> <span class="hljs-keyword">private</span> InetAddress remoteAddress;<span class="hljs-meta">@Valid</span> <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> Security security = <span class="hljs-keyword">new</span> Security();<span class="hljs-comment">// ... getters and setters</span><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Security</span> </span>{<span class="hljs-meta">@NotEmpty</span><span class="hljs-keyword">public</span> String username;<span class="hljs-comment">// ... getters and setters</span>}

    }

    您還可以通過創建名為configurationPropertiesValidator的bean定義來添加自定義的Spring Validator。 @Bean方法應聲明為static。 配置屬性驗證器在應用程序的生命周期早期創建,并聲明@Bean方法,因為static允許創建bean,而無需實例化@Configuration類。 這避免了早期實例化可能引起的任何問題。 這里有一個屬性驗證的例子,所以你可以看到如何設置。

    spring-boot-actuator模塊包括一個暴露所有@ConfigurationProperties bean的端點。 只需將您的Web瀏覽器指向/configprops 或使用等效的JMX端點。 請參閱生產就緒功能 細節。

    24.7.5 @ConfigurationProperties 對比 @Value

    @Value是核心容器功能,它不提供與類型安全配置屬性相同的功能。 下表總結了@ConfigurationProperties和@Value支持的功能:

    功能@ConfigurationProperties@Value
    Relaxed bindingYesNo
    Meta-data supportYesNo
    SpEL evaluationNoYes

    如果您為自己的組件定義了一組配置密鑰,我們建議您將其分組到使用@ConfigurationProperties注釋的POJO中。 還請注意,由于@Value不支持寬松的綁定,如果您需要使用環境變量提供值,那么它不是一個很好的選擇。

    最后,當您可以在@Value中編寫一個Spel表達式時,這些表達式不會從應用程序屬性文件中處理。

    25. 配置文件(Profiles)

    Spring 配置文件提供了將應用程序配置隔離的方法,使其僅在某些環境中可用。 任何@Component或@Configuration都可以使用@Profile進行標記,以限制其在什么時候加載:

    @Configuration @Profile("production") public class ProductionConfiguration { <span class="hljs-comment">// ...</span>

    }

    一般,您可以使用spring.profiles.active Environment屬性來指定哪些配置文件處于激活狀態。 您可以以任何方式指定屬性,例如,您可以將其包含在您的application.properties中:

    spring.profiles.active=dev,hsqldb

    或者使用命令行--spring.profiles.active=dev,hsqldb在命令行中指定。

    25.1添加激活配置文件

    spring.profiles.active屬性遵循與其他屬性相同的優先級規則,PropertySource最高。這意味著您可以在application.properties中指定活動配置文件,然后使用命令行開關替換它們。

    有時,將特定于配置文件的屬性添加到激活的配置文件而不是替換它們是有用的。 spring.profiles.include屬性可用于無條件添加激活配置文件。 SpringApplication入口點還具有用于設置其他配置文件的Java API(即,在由spring.profiles.active屬性激活的那些配置文件之上):請參閱setAdditionalProfiles()方法。

    例如,當使用開關 -spring.profiles.active=prod 運行具有以下屬性的應用程序時,proddb和prodmq配置文件也將被激活:

    --- my.property: fromyamlfile --- spring.profiles: prod spring.profiles.include:- proddb- prodmq

    請記住,可以在YAML文檔中定義spring.profiles屬性,以確定此特定文檔何時包含在配置中。 有關詳細信息,請參見第72.7節“根據環境更改配置”。

    25.2 以編程方式設置配置文件

    您可以通過在應用程序運行之前調用SpringApplication.setAdditionalProfiles(...)以編程方式設置激活配置文件。 也可以使用Spring的ConfigurableEnvironment接口激活配置文件。

    25.3 配置文件指定的配置文件

    通過@ConfigurationProperties引用的application.properties(或application.yml)和文件的配置文件特定變體都被視為加載文件。 有關詳細信息,請參見第24.4節指定配置(Profile-specific)的屬性”。

    26. 日志

    Spring Boot使用Commons Logging進行所有內部日志記錄,但使基礎日志實現開放。 默認配置提供了Java Util Logging,Log4J2和Logback。 在每種情況下,記錄器都預先配置為使用控制臺輸出和可選文件輸出都可用。

    默認情況下,如果使用'Starters',將會使用Logback。 還包括適當的Logback路由,以確保使用Java Util Logging,Commons Logging,Log4J或SLF4J的依賴庫都能正常工作。

    有很多可用于Java的日志記錄框架。 如果上面的列表看起來很混亂,別擔心。 一般來說,您不需要更改日志依賴關系,并且Spring Boot默認值將正常工作。

    26.1 日志格式

    Spring Boot的默認日志輸出如下所示:

    2014-03-05 10:57:51.112 INFO 45469 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/7.0.52 2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext 2014-03-05 10:57:51.253 INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1358 ms 2014-03-05 10:57:51.698 INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/] 2014-03-05 10:57:51.702 INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]

    輸出以下項目:

    • 日期和時間 - 毫秒精度并且容易排序。
    • 日志級別 - ERROR, WARN, INFO, DEBUG, TRACE.
    • 進程ID。
    • ---分隔符來區分實際日志消息的開始。
    • 線程名稱 - 括在方括號中(可能會截斷控制臺輸出)。
    • 記錄器名稱 - 這通常是源類名(通常縮寫)。
    • 日志消息。

    Logback沒有FATAL級別(對映ERROR)

    26.2 控制臺輸出

    默認的日志配置會在控制臺顯示消息。 默認情況下會記錄ERROR,WARN和INFO級別的消息。 您還可以通過--debug啟動您的應用程序來啟用“debug”模式。

    $ java -jar myapp.jar --debug

    您還可以在application.properties中指定debug=true。

    當啟用debug模式時,配置核心記錄器(嵌入式容器,Hibernate和Spring Boot)的選擇可以輸出更多信息。 啟用debug 模式不會將應用程序配置為使用DEBUG級別記錄所有消息。

    或者,您可以使用--trace啟動應用程序(或在您的application.properties中為trace=true)啟用“trace”模式。 這將為核心記錄器(嵌入式容器,Hibernate模式生成和整個Spring組合)啟用trace日志。

    26.2.1 日志顏色輸出

    如果您的終端支持ANSI,顏色輸出可以增加可讀性。 您可以將spring.output.ansi.enabled設置為支持的值來覆蓋自動檢測。

    使用%clr關鍵字配置顏色編碼。 在最簡單的形式下,轉換器將根據日志級別對輸出進行著色,例如:

    %clr(%5p)

    日志級別映射到顏色如下:

    • blue
    • cyan
    • faint
    • green
    • magenta
    • red
    • yellow

    26.3 文件輸出

    默認情況下,Spring Boot將僅將日志輸出到控制臺,不會寫到文件。 如果要將控制臺上的日志輸出到日志文件,則需要設置logging.file或logging.path屬性(例如在application.properties中)。

    下表顯示了如何一起使用logging.*屬性:

    表26.1 Logging屬性

    logging.filelogging.pathExampleDescription
    (none)(none)僅控制臺輸出
    Specific file(none)my.log寫入指定的日志文件。 名稱可以是確切的位置或相對于當前目錄。
    (none)Specific directory/var/log將spring.log寫入指定的目錄。 名稱可以是確切的位置或相對于當前目錄。

    日志文件將在10 MB時滾動輸出到文件,默認情況下會記錄控制臺輸出,ERROR,WARN和INFO級別的消息。

    日志記錄系統在應用程序生命周期早期初始化,并且在通過@PropertySource注解加載的屬性文件中將不會找到log屬性。

    日志屬性獨立于實際的日志記錄基礎結構。 因此,特定配置key(如Logback的logback.configurationFile)不受Spring Boot管理。

    26.4 日志級別

    所有支持的日志記錄系統都可以在Spring Environment 中設置log級別(例如在application.properties中),使用‘logging.level.*=LEVEL’,其中'LEVEL'是TRACE,DEBUG,INFO,WARN,ERROR,FATAL, OFF之一。 可以使用logging.level.root配置根記錄器。 示例application.properties:

    logging.level.root=WARN logging.level.org.springframework.web=DEBUG logging.level.org.hibernate=ERROR

    默認情況下,Spring Boot會重新啟動Thymeleaf INFO消息,以便它們以DEBUG級別進行記錄。 這有助于降低標準日志輸出中的噪音。 有關如何在自己的配置中應用重映射的詳細信息,請參閱LevelRemappingAppender。

    26.5 自定義日志配置

    可以通過在類路徑中包含適當的庫來激活各種日志系統,并通過在類路徑的根目錄中提供合適的配置文件,或在Spring Environment屬性logging.config指定的位置進一步配置。

    您可以使用org.springframework.boot.logging.LoggingSystem系統屬性強制Spring Boot使用特定的日志記錄系統。該值應該是LoggingSystem實現的全名。 您還可以使用none值完全禁用Spring Boot的日志記錄配置。

    由于在創建ApplicationContext之前初始化日志,因此無法在Spring @Configuration文件中控制@PropertySources的日志記錄。 系統屬性和常規的Spring Boot外部配置文件工作正常。

    根據您的日志記錄系統,將會加載以下文件:

    Logging SystemCustomization
    Logbacklogback-spring.xml, logback-spring.groovy, logback.xml or logback.groovy
    Log4j2log4j2-spring.xml or log4j2.xml
    JDK (Java Util Logging)logging.properties

    如果可能,我們建議您使用-spring變體進行日志記錄配置(例如使用logback-spring.xml而不是logback.xml)。 如果使用標準配置位置,則Spring無法完全控制日志初始化。

    Java Util Logging存在已知的類加載問題,從“可執行jar”運行時會導致問題。 我們建議您盡可能避免。

    幫助定制一些其他屬性從Spring環境轉移到系統屬性:

    Spring EnvironmentSystem PropertyComments
    logging.exception-conversion-wordLOG_EXCEPTION_CONVERSION_WORD記錄異常時使用的轉換字。
    logging.fileLOG_FILE如果定義了,則用于默認日志配置。
    logging.pathLOG_PATH如果定義了,則用于默認日志配置。
    logging.pattern.consoleCONSOLE_LOG_PATTERN在控制臺上使用的日志模式(stdout)。 (僅支持默認logback設置。)
    logging.pattern.fileFILE_LOG_PATTERN在文件中使用的日志模式(如果LOG_FILE已啟用)。 (僅支持默認logback設置。)
    logging.pattern.levelLOG_LEVEL_PATTERN用于呈現日志級別的格式(默認%5p)。 (僅支持默認logback設置。)
    PIDPID當前進程ID(如果可能的話,當未被定義為OS環境變量時被發現)。

    支持的所有日志記錄系統在分析其配置文件時可以查看系統屬性。 有關示例,請參閱spring-boot.jar中的默認配置。

    如果要在logging屬性中使用占位符,則應使用Spring Boot的語法,而不是底層框架的語法。 值得注意的是,如果您使用Logback,您應該使用:作為屬性名稱與其默認值之間的分隔符,而不是:-。

    您可以通過覆蓋LOG_LEVEL_PATTERN(或Logback的log.pattern.level)來添加MDC和其他ad-hoc內容到日志行。 例如,如果使用logging.pattern.level = user:%X {user}%5p,則默認日志格式將包含“user”的MDC條目(如果存在)。

    2015-09-30 12:30:04.031 user:juergen INFO 22174 --- [ nio-8080-exec-0] demo.Controller Handling authenticated request

    26.6 Logback擴展

    Spring Boot包括大量的Logback擴展,可以幫助您進行高級配置。 您可以在logback-spring.xml配置文件中使用這些擴展。

    您不能在標準logback.xml配置文件中使用擴展名,因為其加載時間太早。 您需要使用logback-spring.xml或定義logging.config屬性。

    擴展名不能與Logback的配置掃描一起使用。 如果您嘗試這樣做,對配置文件進行更改將導致類似于以下記錄之一的錯誤:

    ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]] ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]

    26.6.1 指定配置文件配置

    <springProfile>標簽允許您根據活動的Spring配置文件可選地包含或排除配置部分。 配置文件部分支持<configuration>元素在任何位置。 使用name屬性指定哪個配置文件接受配置。 可以使用逗號分隔列表指定多個配置文件。

    <springProfile name="staging"><!-- configuration to be enabled when the "staging" profile is active --> </springProfile>

    <springProfile name=“dev, staging”>
    <!-- configuration to be enabled when the “dev” or “staging” profiles are active -->
    </springProfile>

    <springProfile name="!production">
    <!-- configuration to be enabled when the “production” profile is not active -->
    </springProfile>

    26.6.2 環境屬性

    <springProperty>標簽允許您從Spring環境中顯示屬性,以便在Logback中使用。 如果您在logback中訪問application.properties文件中的值,這將非常有用。 標簽的工作方式與Logback標準的<property>標簽類似,但不是指定直接值,而是指定屬性的來源(來自Environment)。 如果需要將屬性存儲在本地范圍以外的位置,則可以使用scope屬性。 如果在環境中未設置屬性的情況下需要備用值,則可以使用defaultValue屬性。

    <springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"defaultValue="localhost"/> <appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender"><remoteHost>${fluentHost}</remoteHost>... </appender>

    RelaxedPropertyResolver用于訪問Environment屬性。 如果以虛線表示法(my-property-name)指定源,則將嘗試所有寬松的變體(myPropertyName,MY_PROPERTY_NAME等)。

    27. 開發Web應用程序

    Spring Boot非常適合Web應用程序開發。 您可以使用嵌入式Tomcat,Jetty或Undertow輕松創建自包含的HTTP服務器。 大多數Web應用程序將使用spring-boot-starter-web模塊快速啟動和運行。

    如果您尚未開發Spring Boot Web應用程序,則可以按照“Hello World!”示例進行操作。 在“入門”部分中的示例。

    27.1 “Spring Web MVC框架”

    Spring Web MVC框架(通常簡稱為“Spring MVC”)是一個豐富的“模型視圖控制器”Web框架。 Spring MVC允許您創建特殊的@Controller或@RestController bean來處理傳入的HTTP請求。 您的控制器中的方法將使用@RequestMapping注釋映射到HTTP。

    以下是@RestController用于提供JSON數據的典型示例:

    @RestController @RequestMapping(value="/users") public class MyRestController { <span class="hljs-meta">@RequestMapping</span>(value=<span class="hljs-string">"/{user}"</span>, method=RequestMethod.GET) <span class="hljs-function"><span class="hljs-keyword">public</span> User <span class="hljs-title">getUser</span><span class="hljs-params">(@PathVariable Long user)</span> </span>{<span class="hljs-comment">// ...</span> }<span class="hljs-meta">@RequestMapping</span>(value=<span class="hljs-string">"/{user}/customers"</span>, method=RequestMethod.GET) <span class="hljs-function">List&lt;Customer&gt; <span class="hljs-title">getUserCustomers</span><span class="hljs-params">(@PathVariable Long user)</span> </span>{<span class="hljs-comment">// ...</span> }<span class="hljs-meta">@RequestMapping</span>(value=<span class="hljs-string">"/{user}"</span>, method=RequestMethod.DELETE) <span class="hljs-function"><span class="hljs-keyword">public</span> User <span class="hljs-title">deleteUser</span><span class="hljs-params">(@PathVariable Long user)</span> </span>{<span class="hljs-comment">// ...</span> }

    }

    Spring MVC是Spring Framework的一部分,詳細信息可在參考文檔中找到。 Spring.io/guide中還有幾個指南可供Spring MVC使用。

    27.1.1 Spring MVC自動配置

    Spring Boot提供了適用于大多數應用程序的Spring MVC的自動配置。

    自動配置在Spring的默認值之上添加以下功能:

    • 包含ContentNegotiatingViewResolver和BeanNameViewResolver bean。
    • 支持提供靜態資源,包括對WebJars的支持(見下文)。
    • Converter,GenericConverter,Formatter beans的自動注冊。
    • 支持HttpMessageConverters(見下文)。
    • 自動注冊MessageCodesResolver(見下文)。
    • 靜態index.html支持。
    • 自定義Favicon支持(見下文)。
    • 自動使用ConfigurableWebBindingInitializer bean(見下文)。

    如果要保留Spring Boot MVC功能,并且您只需要添加其他MVC配置(interceptors, formatters, view, controllers等),你可以添加自己的WebConfigurerAdapter類型的@Configuration類,但不能使用@EnableWebMvc。 如果要提供自定義的RequestMappingHandlerMapping,RequestMappingHandlerAdapter或ExceptionHandlerExceptionResolver實例,您可以聲明一個提供此類組件的WebMvcRegistrationsAdapter實例。

    如果要完全控制Spring MVC,可以使用@EnableWebMvc添加您自己的@Configuration注釋。

    27.1.2 HttpMessageConverters

    Spring MVC使用HttpMessageConverter接口轉換HTTP請求和響應。 包括一些開箱即用的合理配置,例如對象可以自動轉換為JSON(使用Jackson庫)或XML(使用Jackson XML擴展,如果可用,否則使用JAXB)。 字符串默認使用UTF-8進行編碼。

    如果需要添加或自定義轉換器,可以使用Spring Boot HttpMessageConverter類:

    import org.springframework.boot.autoconfigure.web.HttpMessageConverters; import org.springframework.context.annotation.*; import org.springframework.http.converter.*;

    @Configuration
    public class MyConfiguration {

    <span class="hljs-meta">@Bean</span> <span class="hljs-function"><span class="hljs-keyword">public</span> HttpMessageConverters <span class="hljs-title">customConverters</span><span class="hljs-params">()</span> </span>{HttpMessageConverter&lt;?&gt; additional = ...HttpMessageConverter&lt;?&gt; another = ...<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> HttpMessageConverters(additional, another); }

    }

    上下文中存在的任何HttpMessageConverter bean將被添加到轉換器列表中。 您也可以以這種方式覆蓋默認轉換器。

    27.1.3 自定義JSON序列化器和反序列化器

    如果您使用Jackson序列化和反序列化JSON數據,則可能需要編寫自己的JsonSerializer和JsonDeserializer類。 自定義序列化程序通常通過一個模塊注冊到Jackson,但是Spring Boot提供了一個備用的@JsonComponent注釋,可以更容易地直接注冊Spring Bean。

    您可以直接在JsonSerializer或JsonDeserializer實現中使用@JsonComponent。 您也可以將它用于包含序列化器/解串器的類作為內部類。 例如:

    import java.io.*; import com.fasterxml.jackson.core.*; import com.fasterxml.jackson.databind.*; import org.springframework.boot.jackson.*;

    @JsonComponent
    public class Example {

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Serializer</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">JsonSerializer</span>&lt;<span class="hljs-title">SomeObject</span>&gt; </span>{<span class="hljs-comment">// ...</span> }<span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Deserializer</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">JsonDeserializer</span>&lt;<span class="hljs-title">SomeObject</span>&gt; </span>{<span class="hljs-comment">// ...</span> }

    }

    ApplicationContext中的所有@JsonComponent bean將自動注冊到Jackson,并且由于@JsonComponent是使用@Component進行元注解的,所以常規的組件掃描規則適用。

    Spring Boot還提供了JsonObjectSerializer和JsonObjectDeserializer基類,它們在序列化對象時為標準的Jackson版本提供了有用的替代方法。 有關詳細信息,請參閱Javadoc。

    27.1.4 MessageCodesResolver

    Spring MVC有一個生成錯誤代碼的策略,用于從綁定錯誤中提取錯誤消息:MessageCodesResolver。 Spring Boot將為您創建一個錯誤代碼,如果您設置spring.mvc.message-codes-resolver.format屬性PREFIX_ERROR_CODE或POSTFIX_ERROR_CODE(請參閱DefaultMessageCodesResolver.Format中的枚舉)。

    27.1.5 靜態內容

    默認情況下,Spring Boot將從類路徑或ServletContext的根目錄中的名為/static(或/ public或/resources或/META-INF/resources)的目錄提供靜態內容。 它使用Spring MVC中的ResourceHttpRequestHandler,因此您可以通過添加自己的WebMvcConfigurerAdapter并覆蓋addResourceHandlers方法來修改該行為。

    在獨立的Web應用程序中,來自容器的默認servlet也被啟用,并且作為后備,如果Spring決定不處理它,則從ServletContext的根目錄提供內容。 大多數情況下,這不會發生(除非您修改默認的MVC配置),因為Spring將始終能夠通過DispatcherServlet處理請求。

    默認情況下,資源映射到/** ,但可以通過spring.mvc.static-path-pattern調整。 例如,將所有資源重定位到 /resources/**可以配置如下:

    spring.mvc.static-path-pattern=/resources/**

    您還可以使用spring.resources.static-locations(使用目錄位置列表替換默認值)來自定義靜態資源位置。 如果這樣做,默認歡迎頁面檢測將切換到您的自定義位置,因此,如果在啟動時任何位置都有一個index.html,它將是應用程序的主頁。

    除了上述“標準”靜態資源位置之外,還提供了一個特殊情況,用于Webjars內容。 任何具有/ webjars / **中路徑的資源都將從jar文件中提供,如果它們以Webjars格式打包。

    如果您的應用程序將被打包為jar,請不要使用 src/main/webapp 目錄。 雖然這個目錄是一個通用的標準,但它只適用于war包,如果生成一個jar,它將被大多數構建工具忽略。

    Spring Boot還支持Spring MVC提供的高級資源處理功能,允許使用例如緩存靜態資源或使用Webjars的版本無關的URL。

    要為Webjars使用版本無關的URL,只需添加webjars-locator依賴關系即可。然后聲明您的Webjar,以jQuery為例,如“/webjars/jquery/dist/jquery.min.js”,這將產生“/webjars/jquery/xyz/dist/jquery.min.js”,其中xyz是Webjar版本 。

    如果您使用JBoss,則需要聲明webjars-locator-jboss-vfs依賴關系而不是webjars-locator; 否則所有Webjars都將解析為404。

    要使用緩存清除功能,以下配置將為所有靜態資源配置緩存清除解決方案,從而有效地在URL中添加內容哈希值,例如<link href=“/css/spring-2a2d595e6ed9a0b24f027f2b63b134d6.css”/>:

    spring.resources.chain.strategy.content.enabled=true spring.resources.chain.strategy.content.paths=/**

    鏈接資源在運行時在模板中被重寫,這歸功于自動配置為Thymeleaf和FreeMarker的ResourceUrlEncodingFilter。 使用JSP時,應手動聲明此過濾器。 其他模板引擎現在不會自動支持,但可以使用自定義模板宏/幫助程序和使用ResourceUrlProvider。

    當使用例如JavaScript模塊加載器動態加載資源時,重命名文件不是一個選項。這就是為什么其他策略也得到支持并可以合并的原因。 “固定(fixed)”策略將在URL中添加靜態版本字符串,而不更改文件名:

    spring.resources.chain.strategy.content.enabled=true spring.resources.chain.strategy.content.paths=/** spring.resources.chain.strategy.fixed.enabled=true spring.resources.chain.strategy.fixed.paths=/js/lib/ spring.resources.chain.strategy.fixed.version=v12

    使用此配置,位于“/js/lib/”下的JavaScript模塊將使用固定版本策略“/v12/js/lib/mymodule.js”,而其他資源仍將使用內容<link href =“/css/“spring-2a2d595e6ed9a0b24f027f2b63b134d6.css”/>。

    有關更多支持的選項,請參閱ResourceProperties。

    此功能已在專門的博客文章和Spring Framework參考文檔中進行了詳細描述。

    27.1.6 自定義圖標

    Spring Boot在配置的靜態內容位置和類路徑的根目錄(按順序)中查找favicon.ico。 如果文件存在,它將被自動用作應用程序的圖標。

    27.1.7 ConfigurableWebBindingInitializer

    Spring MVC使用WebBindingInitializer為特定請求初始化WebDataBinder。 如果您用@Bean創建自己的ConfigurableWebBindingInitializer @Bean,Spring Boot將自動配置Spring MVC以使用它。

    27.1.8 模板引擎

    除了REST Web服務,您還可以使用Spring MVC來提供動態HTML內容。 Spring MVC支持各種模板技術,包括Thymeleaf,FreeMarker和JSP。 許多其他模板引擎也運行自己的Spring MVC集成。

    Spring Boot包括對以下模板引擎的自動配置支持:

    • FreeMarker
    • Groovy
    • Thymeleaf
    • Mustache

    如果可能,應避免使用JSP,當使用嵌入式servlet容器時,JSP有幾個已知的限制。

    當您使用默認配置的模板引擎之一時,您的模板將從 src/main/resources/templates 自動獲取。

    IntelliJ IDEA根據運行應用程序的方式對類路徑進行不同的排序。 通過main方法在IDE中運行應用程序將導致使用Maven或Gradle打包的jar運行應用程序時的不同順序。這可能會導致Spring Boot找不到類路徑上的模板。 如果您受此問題的影響,您可以重新排序IDE中的類路徑,以放置模塊的類和資源。 或者,您可以配置模板前綴以搜索類路徑上的每個模板目錄:classpath*:/templates/。

    27.1.9 錯誤處理

    默認情況下,Spring Boot提供 /error 映射,以合理的方式處理所有錯誤,并在servlet容器中注冊為“global”錯誤頁面。 對于機器客戶端,它將產生JSON響應,其中包含錯誤,HTTP狀態和異常消息的詳細信息。 對于瀏覽器客戶端,有一個'whitelabel'錯誤視圖,以HTML格式呈現相同的數據(定制它只需添加一個解析“error”的視圖)。 要完全替換默認行為,您可以實現ErrorController并注冊該類型的bean定義,或者簡單地添加一個類型為ErrorAttributes的bean來使用現有機制,但只是替換內容。

    BasicErrorController可以用作自定義ErrorController的基類。 如果要添加新內容類型的處理程序(默認情況下是專門處理text/html并為其他內容提供備選),這一點尤其有用。 要做到這一點,只需擴展BasicErrorController并添加一個帶有@RequestMapping的公共方法,并創建一個新類型的bean。

    您還可以定義一個@ControllerAdvice來自定義為特定控制器 and/or 異常類型返回的JSON文檔。

    @ControllerAdvice(basePackageClasses = FooController.class) public class FooControllerAdvice extends ResponseEntityExceptionHandler { <span class="hljs-meta">@ExceptionHandler</span>(YourException.class) <span class="hljs-meta">@ResponseBody</span> ResponseEntity&lt;?&gt; handleControllerException(HttpServletRequest request, Throwable ex) {HttpStatus status = getStatus(request);<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ResponseEntity&lt;&gt;(<span class="hljs-keyword">new</span> CustomErrorType(status.value(), ex.getMessage()), status); }<span class="hljs-function"><span class="hljs-keyword">private</span> HttpStatus <span class="hljs-title">getStatus</span><span class="hljs-params">(HttpServletRequest request)</span> </span>{Integer statusCode = (Integer) request.getAttribute(<span class="hljs-string">"javax.servlet.error.status_code"</span>);<span class="hljs-keyword">if</span> (statusCode == <span class="hljs-keyword">null</span>) {<span class="hljs-keyword">return</span> HttpStatus.INTERNAL_SERVER_ERROR;}<span class="hljs-keyword">return</span> HttpStatus.valueOf(statusCode); }

    }

    在上面的示例中,如果由FooController在同一個包中定義的控件拋出了YourException,則將使用CustomerErrorType POJO的json表示法而不是ErrorAttributes表示形式。

    自定義錯誤頁面

    如果要顯示給定狀態代碼的自定義HTML錯誤頁面,請將文件添加到/error文件夾。 錯誤頁面可以是靜態HTML(即添加在任何靜態資源文件夾下)或使用模板構建。 該文件的名稱應該是確切的狀態代碼或一個序列掩碼。

    例如,要將404映射到靜態HTML文件,您的文件夾結構將如下所示:

    src/+- main/+- java/| + <source code>+- resources/+- public/+- error/| +- 404.html+- <other public assets>

    要使用FreeMarker模板映射所有5xx錯誤,使用如下結構:

    src/+- main/+- java/| + <source code>+- resources/+- templates/+- error/| +- 5xx.ftl+- <other templates>

    對于更復雜的映射,您還可以添加實現ErrorViewResolver接口的bean。

    public class MyErrorViewResolver implements ErrorViewResolver { <span class="hljs-meta">@Override</span> <span class="hljs-function"><span class="hljs-keyword">public</span> ModelAndView <span class="hljs-title">resolveErrorView</span><span class="hljs-params">(HttpServletRequest request,HttpStatus status, Map&lt;String, Object&gt; model)</span> </span>{<span class="hljs-comment">// Use the request or status to optionally return a ModelAndView</span><span class="hljs-keyword">return</span> ... }

    }

    您還可以使用常規的Spring MVC功能,如@ExceptionHandler方法和@ControllerAdvice。 然后,ErrorController將接收任何未處理的異常。

    映射Spring MVC之外的錯誤頁面

    對于不使用Spring MVC的應用程序,可以使用ErrorPageRegistrar接口來直接注冊ErrorPages。這個抽象直接與底層的嵌入式servlet容器一起工作,即使沒有Spring MVC DispatcherServlet也可以工作。

    @Bean public ErrorPageRegistrar errorPageRegistrar(){return new MyErrorPageRegistrar(); }

    // …

    private static class MyErrorPageRegistrar implements ErrorPageRegistrar {

    <span class="hljs-meta">@Override</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">registerErrorPages</span><span class="hljs-params">(ErrorPageRegistry registry)</span> </span>{registry.addErrorPages(<span class="hljs-keyword">new</span> ErrorPage(HttpStatus.BAD_REQUEST, <span class="hljs-string">"/400"</span>)); }

    }

    N.B. 如果您注冊一個最終由Filter過濾的路徑的ErrorPage(例如,像一些非Spring Web框架,例如Jersey和Wicket一樣),則必須將Filter顯式注冊為ERROR dispatcher,例如。

    @Bean public FilterRegistrationBean myFilter() {FilterRegistrationBean registration = new FilterRegistrationBean();registration.setFilter(new MyFilter());...registration.setDispatcherTypes(EnumSet.allOf(DispatcherType.class));return registration; }

    (默認的FilterRegistrationBean不包括ERROR dispatcher 類型)。

    WebSphere Application Server上的錯誤處理

    當部署到servlet容器時,Spring Boot會使用其錯誤頁面過濾器將具有錯誤狀態的請求轉發到相應的錯誤頁面。 如果響應尚未提交,則該請求只能轉發到正確的錯誤頁面。 默認情況下,WebSphere Application Server 8.0及更高版本在成功完成servlet的服務方法后提交響應。 您應該通過將com.ibm.ws.webcontainer.invokeFlushAfterService設置為false來禁用此行為

    27.1.10 Spring HATEOAS

    如果您正在開發一種利用超媒體的RESTful API,Spring Boot可以為Spring HATEOAS提供自動配置,適用于大多數應用程序。 自動配置取代了使用@EnableHypermediaSupport的需求,并注冊了一些Bean,以便輕松構建基于超媒體的應用程序,包括LinkDiscoverers(用于客戶端支持)和配置為將響應正確地組織到所需表示中的ObjectMapper。 ObjectMapper將根據spring.jackson。*屬性或Jackson2ObjectMapperBuilder bean(如果存在)進行自定義。

    您可以使用@EnableHypermediaSupport控制Spring HATEOAS配置。 請注意,這將禁用上述ObjectMapper定制。

    27.1.11 CORS 支持

    跨原始資源共享(CORS)是大多數瀏覽器實現的W3C規范,允許您以靈活的方式指定什么樣的跨域請求被授權,而不是使用一些不太安全和不太強大的方法,如IFRAME或JSONP。

    從版本4.2起,Spring MVC支持CORS開箱即用。 在Spring Boot應用程序中的controller方法使用@CrossOrigin注解的CORS配置不需要任何特定的配置。 可以通過使用自定義的addCorsMappings(CorsRegistry)方法注冊WebMvcConfigurer bean來定義全局CORS配置:

    @Configuration public class MyConfiguration { <span class="hljs-meta">@Bean</span> <span class="hljs-function"><span class="hljs-keyword">public</span> WebMvcConfigurer <span class="hljs-title">corsConfigurer</span><span class="hljs-params">()</span> </span>{<span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> WebMvcConfigurerAdapter() {<span class="hljs-meta">@Override</span><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">addCorsMappings</span><span class="hljs-params">(CorsRegistry registry)</span> </span>{registry.addMapping(<span class="hljs-string">"/api/**"</span>);}}; }

    }

    27.2 JAX-RS 和 Jersey

    如果您喜歡JAX-RS編程模型的REST endpoints ,您可以使用一個可用的實現而不是Spring MVC。 如果您剛剛在應用程序上下文中注冊了一個@Bean的Servlet或Filter,那么Jersey 1.x和Apache CXF的功能非常出色。 Jersey2.x有一些本地Spring支持,所以我們也提供自動配置支持它在Spring Boot與啟動器。

    要開始使用Jersey 2.x,只需將spring-boot-starter-jersey作為依賴項,然后您需要一個@Bean類型ResourceConfig,您可以在其中注冊所有端點(endpoints):

    @Component public class JerseyConfig extends ResourceConfig { <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">JerseyConfig</span><span class="hljs-params">()</span> </span>{register(Endpoint.class); }

    }

    Jersey對掃描可執行檔案的包是相當有限的。 例如,當運行可執行的war文件時,它無法掃描在WEB-INF/classes中找到的包中的端點(endpoints)。 為了避免這種限制,不應使packages方法,并且應使用上述寄存器方法單獨注冊(register)端點。

    您還可以注冊任意數量的ResourceConfigCustomizer的實現bean,以實現更高級的自定義。

    所有注冊的端點都應為具有HTTP資源注解(@GET等)的@Components,例如。

    @Component @Path("/hello") public class Endpoint { <span class="hljs-meta">@GET</span> <span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">message</span><span class="hljs-params">()</span> </span>{<span class="hljs-keyword">return</span> <span class="hljs-string">"Hello"</span>; }

    }

    由于Endpoint是一個Spring @Component,所以Spring的生命周期由Spring管理,您可以使用@Autowired依賴關系并使用@Value注入外部配置。 默認情況下,Jersey servlet將被注冊并映射到/ *。 您可以通過將@ApplicationPath添加到ResourceConfig來更改映射。

    默認情況下,Jersey將通過@Bean以名為jerseyServletRegistration的ServletRegistrationBean類型在Servlet進行設置。 默認情況下,servlet將被初始化,但是您可以使用spring.jersey.servlet.load-on-startup進行自定義。您可以通過創建一個自己的同名文件來禁用或覆蓋該bean。 您也可以通過設置spring.jersey.type = filter(在這種情況下,@Bean來替換或替換為jerseyFilterRegistration),使用Filter而不是Servlet。 servlet有一個@Order,您可以使用spring.jersey.filter.order設置。 可以使用spring.jersey.init.* 給出Servlet和過濾器注冊的init參數,以指定屬性的映射。

    有一個Jersey示例,所以你可以看到如何設置。 還有一個Jersey1.x示例。 請注意,在Jersey1.x示例中,spring-boot maven插件已經被配置為打開一些Jersey jar,以便它們可以被JAX-RS實現掃描(因為示例要求它們在Filter注冊中進行掃描) 。 如果您的任何JAX-RS資源作為嵌套的jar打包,您可能需要執行相同操作。

    27.3 嵌入式servlet容器支持

    Spring Boot包括對嵌入式Tomcat,Jetty和Undertow服務器的支持。 大多數開發人員將簡單地使用適當的“Starter”來獲取完全配置的實例。 默認情況下,嵌入式服務器將監聽端口8080上的HTTP請求。

    如果您選擇在CentOS上使用Tomcat,請注意,默認情況下,臨時目錄用于存儲已編譯的JSP,文件上傳等。當您的應用程序正在運行導致故障時,該目錄可能會被tmpwatch刪除。 為了避免這種情況,您可能需要自定義tmpwatch配置,以便tomcat.*目錄不被刪除,或配置server.tomcat.basedir,以便嵌入式Tomcat使用不同的位置

    27.3.1 Servlets, Filters 和 listeners

    當使用嵌入式servlet容器時,可以使用Spring bean或通過掃描Servlet組件(例如HttpSessionListener)注冊Servlet規范中的Servlet,過濾器和所有監聽器。

    將Servlets,過濾器和監聽器注冊為Spring bean

    任何Servlet,Filter或Servlet Listener 實例都會作為Spring bean注冊到嵌入式容器中。 可以非常方便地在配置過程中引用您的application.properties中的值。

    默認情況下,如果容器中只包含一個Servlet,它將映射到/。 在多個Servlet bean的情況下,bean名稱將作為路徑前綴。 過濾器(Filters)將映射到/*,默認過濾所有請求。

    如果基于慣例的映射不夠靈活,可以使用ServletRegistrationBean,FilterRegistrationBean和ServletListenerRegistrationBean類來完成控制。

    27.3.2 Servlet Context 初始化

    嵌入式servlet容器不會直接執行Servlet 3.0+ javax.servlet.ServletContainerInitializer接口或Spring的org.springframework.web.WebApplicationInitializer接口。 這樣設計的目的旨在降低在war中運行的第三方庫破壞Spring Boot應用程序的風險。

    如果您需要在Spring Boot應用程序中執行servlet context 初始化,則應注冊一個實現org.springframework.boot.context.embedded.ServletContextInitializer接口的bean。 單個onStartup方法提供對ServletContext的訪問,并且如果需要,可以輕松地用作現有WebApplicationInitializer的適配器。

    掃描Servlet,過濾器和監聽器

    使用嵌入式容器時,可以使用@ServletComponentScan啟用@WebServlet,@WebFilter和@WebListener注解類的自動注冊。

    @ServletComponentScan在獨立容器中不起作用,在該容器中將使用容器的內置發現機制。

    27.3.3 EmbeddedWebApplicationContext

    在Spring Boot引導下,將會使用一種新類型的ApplicationContext來支持嵌入式的servlet容器。 EmbeddedWebApplicationContext是一種特殊類型的WebApplicationContext,它通過搜索單個EmbeddedServletContainerFactory bean來引導自身。 通常,TomcatEmbeddedServletContainerFactory,JettyEmbeddedServletContainerFactory或UndertowEmbeddedServletContainerFactory將被自動配置。

    您通常不需要知道這些實現類。 大多數應用程序將被自動配置,并將代表您創建適當的ApplicationContext和EmbeddedServletContainerFactory。

    27.3.4 定制嵌入式servlet容器

    可以使用Spring Environment屬性配置常見的servlet容器設置。 通常您可以在application.properties文件中定義屬性。

    常用服務器設置包括:

    • 網絡設置:偵聽端口的HTTP請求(server.port),接口地址綁定到server.address等。
    • 會話設置:會話是否持久化(server.session.persistence),會話超時(server.session.timeout),會話數據的位置(server.session.store-dir)和session-cookie配置(server.session.cookie.*)。
    • 錯誤管理:錯誤頁面的位置(server.error.path)等
    • SSL
    • HTTP壓縮

    Spring Boot盡可能地嘗試公開常見設置,但并不總是可能的。 對于這些情況,專用命名空間提供服務器特定的定制(請參閱server.tomcat和server.undertow)。 例如,可以使用嵌入式servlet容器的特定功能來配置訪問日志。

    有關完整列表,請參閱 ServerProperties 類。

    用程序定制

    如果需要以編程方式配置嵌入式servlet容器,您可以注冊一個實現EmbeddedServletContainerCustomizer接口的Spring bean。 EmbeddedServletContainerCustomizer提供對ConfigurableEmbeddedServletContainer的訪問,其中包含許多自定義設置方法。

    import org.springframework.boot.context.embedded.*; import org.springframework.stereotype.Component;

    @Component
    public class CustomizationBean implements EmbeddedServletContainerCustomizer {

    <span class="hljs-meta">@Override</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">customize</span><span class="hljs-params">(ConfigurableEmbeddedServletContainer container)</span> </span>{container.setPort(<span class="hljs-number">9000</span>); }

    }

    直接自定義ConfigurableEmbeddedServletContainer

    如果上述定制技術有太多限制,您可以自己注冊TomcatEmbeddedServletContainerFactory,JettyEmbeddedServletContainerFactory或UndertowEmbeddedServletContainerFactory bean。

    @Bean public EmbeddedServletContainerFactory servletContainer() {TomcatEmbeddedServletContainerFactory factory = new TomcatEmbeddedServletContainerFactory();factory.setPort(9000);factory.setSessionTimeout(10, TimeUnit.MINUTES);factory.addErrorPages(new ErrorPage(HttpStatus.NOT_FOUND, "/notfound.html"));return factory; }

    setter方法提供了許多配置選項。 如果您需要做更多的自定義,還會提供幾種保護方法“鉤子”。 有關詳細信息,請參閱源代碼文檔。

    27.3.5 JSP限制

    當運行使用嵌入式servlet容器(并打包為可執行文檔)的Spring Boot應用程序時,對JSP支持有一些限制。

    • 可以使用Tomcat和war包,即可執行的war將會起作用,并且也可以部署到標準容器(不限于但包括Tomcat)中。 由于Tomcat中的硬編碼文件模式,可執行的jar將無法正常工作。
    • 可以使用Jetty和war包,即可執行的war將會起作用,并且也可以部署到任何標準的容器,它應該可以工作。
    • Undertow不支持JSP。
    • 創建自定義的error.jsp頁面將不會覆蓋默認視圖以進行錯誤處理,而應使用自定義錯誤頁面。

    28. Security

    如果Spring Security位于類路徑上,則默認情況下,Web應用程序將在所有HTTP端點上使用“basic”身份驗證。 要向Web應用程序添加方法級安全性,您還可以使用所需的設置添加@EnableGlobalMethodSecurity。 有關更多信息,請參見“Spring Security Reference”。

    默認的AuthenticationManager有一個用戶(用戶名'user'和隨機密碼,在應用程序啟動時以INFO級別打印)

    Using default security password: 78fa095d-3f4c-48b1-ad50-e24c31d5cf35

    如果您調整日志記錄配置,請確保將org.springframework.boot.autoconfigure.security類別設置為記錄INFO消息,否則將不會打印默認密碼。

    您可以通過提供security.user.password來更改密碼。 這個和其他有用的屬性通過 SecurityProperties(屬性前綴“security”)進行外部化。

    默認的安全配置在SecurityAutoConfiguration和從那里導入的類中實現(用于Web安全的SpringBootWebSecurityConfiguration和用于認證配置的AuthenticationManagerConfiguration,這在非Web應用程序中也是相關的)。 要完全關閉默認的Web應用程序安全配置,您可以使用@EnableWebSecurity添加一個bean(這不會禁用身份驗證管理器配置或Actuator的安全性)。 要定制它,您通常使用WebSecurityConfigurerAdapter類型的外部屬性和bean(例如添加基于表單的登錄)。 要關閉身份驗證管理器配置,您可以添加AuthenticationManager類型的bean,或者通過將AuthenticationManagerBuilder自動連接到您的一個@Configuration類中的方法來配置全局AuthenticationManager。 Spring Boot示例中有幾個安全應用程序可以讓您開始使用常見的用例。

    您在Web應用程序中獲得的基本功能包括:

    • 具有內存存儲和單個用戶的AuthenticationManager Bean(請參閱用于用戶屬性的SecurityProperties.User)。
    • 對于常見的靜態資源位置,忽略(不安全)路徑(/css/**, /js/**, /images/**, /webjars/** and **/favicon.ico)。
    • HTTP所有其他端點的baseic security 。
    • 安全事件發布到Spring的ApplicationEventPublisher(成功、不成功的身份驗證、拒絕訪問)。
    • 默認情況下,Spring Security提供的常見的底層功能(HSTS,XSS,CSRF,緩存)都是打開的。

    所有上述可以使用外部屬性(security.*)打開、關閉或修改。 要覆蓋訪問規則而不更改任何其他自動配置的功能,請添加一個帶有@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)的WebSecurityConfigurerAdapter類型的Bean,并配置它以滿足您的需要。

    默認情況下,WebSecurityConfigurerAdapter將匹配任何路徑。 如果您不想完全覆蓋Spring Boot自動配置的訪問規則,您的適配器必須顯式配置您要覆蓋的路徑。

    28.1 OAuth2

    如果您的類路徑中有spring-security-oauth2,您可以利用一些自動配置來輕松設置授權或資源服務器。 有關完整的詳細信息,請參閱“Spring Security OAuth 2開發人員指南”。

    28.1.1 授權服務器

    要創建授權服務器并授予訪問令牌,您需要使用@EnableAuthorizationServer并提供security.oauth2.client.client-id和security.oauth2.client.client-secret]屬性。 客戶端將為您注冊在內存中。

    $ curl client:secret@localhost:8080/oauth/token -d grant_type=password -d username=user -d password=pwd

    /token 端點的基本身份驗證憑證是client-id和client-secret。 用戶憑據是普通的Spring Security用戶details (在Spring引導中默認為“user”和隨機密碼)。

    要關閉自動配置并自行配置授權服務器功能,只需添加一個類型為AuthorizationServerConfigurer的@Bean。

    28.1.2 資源服務器

    要使用訪問令牌(token),您需要一個資源服務器(可以與授權服務器相同)。 創建資源服務器很簡單,只需添加@EnableResourceServer并提供一些配置,以允許服務器解碼訪問令牌。 如果您的應用程序也是授權服務器,則它已經知道如何解碼令牌,無需做其他事情。 如果你的應用程序是一個獨立的服務,那么你需要給它一些更多的配置,以下選項之一:

    • security.oauth2.resource.user-info-uri使用/me資源(例如PWS上的https://uaa.run.pivotal.io/userinfo)
    • security.oauth2.resource.token-info-uri使用令牌解碼端點(例如,PWS上的https://uaa.run.pivotal.io/check_token)。

    如果您同時指定user-info-uri和token-info-uri,那么您可以設置一個標志,表示優先于另一個(prefer-token-inf=true是默認值)。

    或者(不是user-info-uri或token-info-uri的情況)如果令牌是JWT,您可以配置security.oauth2.resource.jwt.key-value來本地解碼(key是驗證密鑰verification key)。 驗證密鑰值是對稱秘密或PEM編碼的RSA公鑰。 如果您沒有密鑰,并且它是公開的,您可以提供一個可以使用security.oauth2.resource.jwt.key-uri下載的URI(具有“value”字段的JSON對象)。 例如在PWS上:

    $ curl https://uaa.run.pivotal.io/token_key {"alg":"SHA256withRSA","value":"-----BEGIN PUBLIC KEY-----\nMIIBI...\n-----END PUBLIC KEY-----\n"}

    如果您使用security.oauth2.resource.jwt.key-uri,則應用程序啟動時需要運行授權服務器。 如果找不到密鑰,它將記錄一個警告,并告訴您如何解決該問題。

    如果您使用security.oauth2.resource.jwt.key-uri,則應用程序啟動時需要運行授權服務器。 如果找不到密鑰,它將會在日志記錄一個警告,并告訴您如何解決該問題。

    OAuth2資源由order security.oauth2.resource.filter-order的過濾器鏈保護,默認情況下保護執行器(actuator)端點的過濾器(所以執行器(actuator)端點將保留在HTTP Basic上,除非更改順序)。

    28.2 User Info中的令牌類型

    Google和某些其他第三方身份認證提供商對在header中發送到用戶信息端點的令牌類型名稱更為嚴格。 默認值為“Bearer”,適合大多數提供程序并匹配規范,但如果需要更改,可以設置security.oauth2.resource.token-type。

    28.3 自定義用戶信息RestTemplate

    如果您有user-info-uri,則資源服務器功能在內部使用OAuth2RestTemplate來獲取用戶身份驗證信息。 這是以UserInfoRestTemplateFactory類型的@Bean提供的。 大多數提供程序的默認值應該是能滿足正常使用,但有時您可能需要添加其他攔截器,或者更改請求驗證器(例如:令牌如何附加到傳出請求)。 進行自定義,只需創建一個類型為UserInfoRestTemplateCustomizer的bean - 它具有一個方法,在bean創建之后但在初始化之前將被調用。 這里定制的rest模板只能在內部進行驗證。 或者,您可以定義自己的UserInfoRestTemplateFactory @Bean來完全控制。

    要在YAML中設置RSA密鑰值,請使用“pipe”繼續標記將其分割成多行(“|”),并記住縮進鍵值(它是標準的 YAML 語言功能)。 例:

    security:oauth2:resource:jwt:keyValue: |-----BEGIN PUBLIC KEY-----MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC...-----END PUBLIC KEY-----

    28.3.1 Client

    要使您的 web-app 進入OAuth2客戶端,您可以簡單地添加@ EnableOAuth2Client,Spring Boot將創建一個OAuth2ClientContext和OAuth2ProtectedResourceDetails,這些是創建OAuth2RestOperations所必需的。 Spring Boot不會自動創建這樣的bean,但是您可以輕松創建自己的bean:

    @Bean public OAuth2RestTemplate oauth2RestTemplate(OAuth2ClientContext oauth2ClientContext,OAuth2ProtectedResourceDetails details) {return new OAuth2RestTemplate(details, oauth2ClientContext); }

    您可能需要添加限定符并查看您的配置,因為您的應用程序可能會定義多個RestTemplate。

    此配置使用security.oauth2.client.*作為憑據(可能與授權服務器中使用的相同),但另外還需要知道授權服務器中的授權和令牌URI。 例如:

    application.yml.

    security:oauth2:client:clientId: bd1c0a783ccdd1c9b9e4clientSecret: 1a9030fbca47a5b2c28e92f19050bb77824b5ad1accessTokenUri: https://github.com/login/oauth/access_tokenuserAuthorizationUri: https://github.com/login/oauth/authorizeclientAuthenticationScheme: form

    當您嘗試使用OAuth2RestTemplate時,具有此配置的應用程序將重定向到Github進行授權。 如果您已經登錄Github,您甚至不會注意到它已經被認證。 如果您的應用程序在端口8080上運行(在Github或其他提供商注冊自己的客戶端應用程序以獲得更大的靈活性),這些特定的憑據才會起作用。

    要限制客戶端在獲取訪問令牌時要求的范圍,您可以設置security.oauth2.client.scope(逗號分隔或YAML中的數組)。 默認情況下,scope是空的,由授權服務器決定其默認值,通常取決于客戶端注冊中的設置。

    還有一個security.oauth2.client.client-authentication-scheme的設置,默認為“header”(但是如果像Github那樣,您可能需要將其設置為“form”,例如,您的OAuth2提供程序不喜歡header 認證)。 事實上,security.oauth2.client.*屬性綁定到AuthorizationCodeResourceDetails的一個實例,因此可以指定其所有的屬性。

    在非Web應用程序中,您仍然可以創建一個OAuth2RestOperations,它仍然連接到security.oauth2.client.*配置中。 在這種情況下,它是一個“客戶端憑據令牌授予”,您如果使用它就請求它(并且不需要使用@EnableOAuth2Client或@EnableOAuth2Sso)。為了防止定義基礎設施,只需從配置中刪除security.oauth2.client.client-id(或使其成為空字符串)。

    28.3.2 單點登錄

    OAuth2客戶端可用于從提供商獲取用戶詳細信息(如果此類功能可用),然后將其轉換為Spring Security的身份驗證令牌。 以上資源服務器通過user-info-uri屬性支持此功能這是基于OAuth2的單點登錄(SSO)協議的基礎,Spring Boot可以通過提供@ EnableOAuth2Sso注解來輕松加入。 上面的Github客戶端可以通過添加該注釋并聲明在何處查找端點(除了上面列出的security.oauth2.client.*配置)外,還可以保護所有資源并使用Github/user/endpoint進行身份驗證:

    application.yml.

    security:oauth2: ...resource:userInfoUri: https://api.github.com/userpreferTokenInfo: false

    由于默認情況下所有路徑都是安全的,所以沒有可以向未經身份驗證的用戶顯示“家”頁面,并邀請他們登錄(通過訪問/登錄路徑或由security.oauth2.sso.login-path指定的路徑) 。

    由于默認情況下所有路徑都是要求安全的,所以沒有可以向未經身份驗證的用戶顯示“home”頁面,并邀請他們登錄(通過訪問/login 路徑或由security.oauth2.sso.login-path指定的路徑) 。

    要自定義保護的訪問規則或路徑,因此您可以添加“home”頁面,例如,@EnableOAuth2Sso可以添加到WebSecurityConfigurerAdapter,并且注解將使其被修飾和增強,以使所需的/login路徑可以工作。 例如,這里我們簡單地允許未經身份驗證的訪問“/"下的主頁面,并保留其他所有內容的默認值:

    @Configuration public class WebSecurityConfiguration extends WebSecurityConfigurerAdapter { <span class="hljs-meta">@Override</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">init</span><span class="hljs-params">(WebSecurity web)</span> </span>{web.ignore(<span class="hljs-string">"/"</span>); }<span class="hljs-meta">@Override</span> <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">void</span> <span class="hljs-title">configure</span><span class="hljs-params">(HttpSecurity http)</span> <span class="hljs-keyword">throws</span> Exception </span>{http.antMatcher(<span class="hljs-string">"/**"</span>).authorizeRequests().anyRequest().authenticated(); }

    }

    28.4 Actuator Security

    如果Actuator也在使用中,您會發現:

    • 即使應用程序端點不安全,管理端點也是安全的。
    • Security 事件將轉換為AuditEvent實例,并發布到AuditEventRepository。
    • 默認用戶將具有ACTUATOR角色以及USER角色。

    Actuator的安全功能可以使用外部屬性(management.security.*)進行修改。要覆蓋應用程序訪問規則,請添加一個類型為WebSecurityConfigurerAdapter的@Bean,如果您不想覆蓋執行程序訪問規則,則使用@Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)或@Order(ManagementServerProperties.ACCESS_OVERRIDE_ORDER)覆蓋執行器訪問規則。

    29. 使用SQL數據庫

    Spring Framework 為使用SQL數據庫提供了廣泛的支持。 從使用JdbcTemplate直接JDBC訪問到完成“對象關系映射”技術,如Hibernate。Spring Data提供了額外的功能,直接從接口創建Repository實現,并使用約定從方法名稱生成查詢。

    29.1 配置DataSource

    Java的javax.sql.DataSource接口提供了使用數據庫連接的標準方法。傳統上,DataSource使用URL和一些憑據來建立數據庫連接。

    還可以查看更多高級示例的“操作方法”部分,通常可以完全控制DataSource的配置。

    29.1.1 嵌入式數據庫支持

    使用內存中嵌入式數據庫開發應用程序通常很方便。 顯然,內存數據庫不提供持久化存儲; 您的應用程序啟動時,您將需要初始化數據庫,并在應用程序結束時丟棄數據。

    “How-to”部分包含如何初始化數據庫

    Spring Boot可以自動配置嵌入式 H2,HSQL 和 Derby 數據庫。 您不需要提供任何連接URL,只需將要使用的嵌入式數據庫的依賴關系包含進去即可。

    如果您在測試中使用此功能,您可能會注意到,整個測試套件都會重復使用相同的數據庫,而不管您使用的應用程序上下文的數量。 如果要確保每個上下文都有一個單獨的嵌入式數據庫,您應該將spring.datasource.generate-unique-name設置為true。

    例如,典型的POM依賴關系是:

    <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency><groupId>org.hsqldb</groupId><artifactId>hsqldb</artifactId><scope>runtime</scope> </dependency>

    對于要自動配置的嵌入式數據庫,您需要依賴spring-jdbc。 在這個例子中,它是通過spring-boot-starter-data-jpa傳遞的。

    如果由于某種原因配置嵌入式數據庫的連接URL,則應注意確保數據庫的自動關閉被禁用。 如果你使用H2,你應該使用DB_CLOSE_ON_EXIT=FALSE這樣做。 如果您使用HSQLDB,則應確保不使用shutdown=true。 禁用數據庫的自動關閉允許Spring Boot控制數據庫何時關閉,從而確保在不再需要訪問數據庫時發生這種情況。

    29.1.2 連接到生產環境數據庫

    生產數據庫連接也可以使用連接池數據源自動配置。 這是選擇具體實現的算法:

    • 我們更喜歡Tomcat連接池DataSource的性能和并發性,所以如果可用,我們總是選擇它。
    • 否則,如果HikariCP可用,我們將使用它。
    • 如果Tomcat池數據源和HikariCP都不可用,并且如果Commons DBCP可用,我們將使用它,但是我們不建議在生產中使用它,并且不支持它。
    • 最后,如果Commons DBCP2可用,我們將使用它。

    如果您使用spring-boot-starter-jdbc或spring-boot-starter-data-jpa 的startters,您將自動獲得對tomcat-jdbc的依賴。

    您可以完全繞過該算法,并通過spring.datasource.type屬性指定要使用的連接池。 如果您在Tomcat容器中運行應用程序,則默認情況下提供tomcat-jdbc,這一點尤為重要。

    可以隨時手動配置其他連接池。如果您定義自己的DataSource bean,則不會發生自動配置。

    DataSource配置由spring.datasource中的外部配置屬性控制。 例如,您可以在application.properties中聲明以下部分:

    spring.datasource.url=jdbc:mysql://localhost/test spring.datasource.username=dbuser spring.datasource.password=dbpass spring.datasource.driver-class-name=com.mysql.jdbc.Driver

    您應至少使用spring.datasource.url屬性指定url,否則Spring Boot將嘗試自動配置嵌入式數據庫。

    您通常不需要指定驅動程序類名稱,因為Spring Boot可以從url為大多數數據庫推斷出驅動程序名稱。

    對于要創建的池數據源,我們需要能夠驗證有效的Driver類是否可用,所以我們在做任何事情之前檢查它。 即 如果您設置spring.datasource.driver-class-name=com.mysql.jdbc.Driver,那么該類必須可加載。

    有關更多支持的選項,請參閱 DataSourceProperties。 這些是標準選項,無論實際執行情況如何。 還可以使用各自的前綴(spring.datasource.tomcat.*,spring.datasource.hikari.*和spring.datasource.dbcp2.*)微調實現特定的設置。 有關更多詳細信息,請參閱您正在使用的連接池實現的文檔。

    例如,如果您正在使用Tomcat連接池,您可以自定義許多其他設置:

    # Number of ms to wait before throwing an exception if no connection is available. spring.datasource.tomcat.max-wait=10000 # Maximum number of active connections that can be allocated from this pool at the same time. spring.datasource.tomcat.max-active=50 # Validate the connection before borrowing it from the pool. spring.datasource.tomcat.test-on-borrow=true

    29.1.3 連接到JNDI DataSource

    如果要將Spring Boot應用程序部署到應用程序服務器,則可能需要使用應用程序服務器內置功能來配置和管理DataSource,并使用JNDI進行訪問。

    spring.datasource.jndi-name屬性可以用作spring.datasource.url,spring.datasource.username和spring.datasource.password屬性的替代方法,以從特定的JNDI位置訪問DataSource。 例如,application.properties中的以下部分顯示了如何訪問JBoss AS定義的DataSource:

    spring.datasource.jndi-name=java:jboss/datasources/customers

    29.2 使用JdbcTemplate

    Spring的JdbcTemplate和NamedParameterJdbcTemplate類是自動配置的,您可以將它們直接連接到您自己的bean中:

    import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Component;

    @Component
    public class MyBean {

    <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> JdbcTemplate jdbcTemplate;<span class="hljs-meta">@Autowired</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">MyBean</span><span class="hljs-params">(JdbcTemplate jdbcTemplate)</span> </span>{<span class="hljs-keyword">this</span>.jdbcTemplate = jdbcTemplate; }<span class="hljs-comment">// ...</span>

    }

    29.3 JPA 和 ‘Spring Data’

    Java Persistence API是一種標準技術,可讓您將對象映射到關系數據庫。 spring-boot-starter-data-jpa POM提供了一種快速入門的方法。 它提供以下關鍵依賴:

    • Hibernate - 最受歡迎的JPA實現之一。
    • Spring Data JPA - 可以輕松實現基于JPA的存儲庫。
    • Spring ORMs - 來自Spring Framework的核心ORM支持。

    我們不會在這里介紹太多的JPA或Spring Data的細節。 您可以從spring.io中查看“使用JPA訪問數據”指南,并閱讀Spring Data JPA和Hibernate參考文檔。

    默認情況下,Spring Boot使用Hibernate 5.0.x. 但是,如果您愿意,也可以使用4.3.x或5.2.x。 請參考 Hibernate 4 和 Hibernate 5.2 示例,看看如何做到這一點。

    29.3.1 實體類

    傳統上,JPA'Entity'類在persistence.xml文件中指定。 使用Spring Boot此文件不是必需的,而是使用“實體掃描”。 默認情況下,將搜索主配置類下面的所有包(用@EnableAutoConfiguration或@SpringBootApplication注解的類)。

    任何用@Entity,@Embeddable或@MappedSuperclass注解的類將被考慮。 典型的實體類將如下所示:

    package com.example.myapp.domain;

    import java.io.Serializable;
    import javax.persistence.*;

    @Entity
    public class City implements Serializable {

    <span class="hljs-meta">@Id</span> <span class="hljs-meta">@GeneratedValue</span> <span class="hljs-keyword">private</span> Long id;<span class="hljs-meta">@Column</span>(nullable = <span class="hljs-keyword">false</span>) <span class="hljs-keyword">private</span> String name;<span class="hljs-meta">@Column</span>(nullable = <span class="hljs-keyword">false</span>) <span class="hljs-keyword">private</span> String state;<span class="hljs-comment">// ... additional members, often include @OneToMany mappings</span><span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-title">City</span><span class="hljs-params">()</span> </span>{<span class="hljs-comment">// no-args constructor required by JPA spec</span><span class="hljs-comment">// this one is protected since it shouldn't be used directly</span> }<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">City</span><span class="hljs-params">(String name, String state)</span> </span>{<span class="hljs-keyword">this</span>.name = name;<span class="hljs-keyword">this</span>.country = country; }<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getName</span><span class="hljs-params">()</span> </span>{<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.name; }<span class="hljs-function"><span class="hljs-keyword">public</span> String <span class="hljs-title">getState</span><span class="hljs-params">()</span> </span>{<span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.state; }<span class="hljs-comment">// ... etc</span>

    }

    您可以使用@EntityScan注解自定義實體掃描位置。 請參見第77.4節“從Spring配置中分離@Entity定義”操作方法。

    29.3.2 Spring Data JPA Repositories

    Spring Data JPA庫是可以定義用于訪問數據的接口。 JPA查詢是從您的方法名稱自動創建的。 例如,CityRepository接口可以聲明findAllByState(String state)方法來查找給定狀態下的所有城市。

    對于更復雜的查詢,您可以使用Spring數據查詢注解來注解您的方法。

    Spring數據存儲庫通常從Repository或CrudRepository接口擴展。 如果您正在使用自動配置,將從包含主配置類(通過@EnableAutoConfiguration或@SpringBootApplication注解的包)的包中搜索存儲庫(repositories)。

    這是一個典型的Spring數據庫:

    package com.example.myapp.domain;

    import org.springframework.data.domain.;
    import org.springframework.data.repository.;

    public interface CityRepository extends Repository<City, Long> {

    <span class="hljs-function">Page&lt;City&gt; <span class="hljs-title">findAll</span><span class="hljs-params">(Pageable pageable)</span></span>;<span class="hljs-function">City <span class="hljs-title">findByNameAndCountryAllIgnoringCase</span><span class="hljs-params">(String name, String country)</span></span>;

    }

    我們只是觸及了Spring Data JPA的表面。 有關完整的詳細信息,請查閱其參考文檔。

    29.3.3 創建和刪除JPA數據庫

    默認情況下,僅當您使用嵌入式數據庫(H2,HSQL或Derby)時才會自動創建JPA數據庫。 您可以使用spring.jpa。*屬性顯式配置JPA設置。 例如,要創建和刪除表,您可以將以下內容添加到application.properties中。

    spring.jpa.hibernate.ddl-auto=create-drop

    Hibernate自己的內部屬性名稱(如果你記得更好)是hibernate.hbm2ddl.auto。您可以使用spring.jpa.properties *(將其添加到實體管理器時這個前綴會被刪除)與其他Hibernate屬性一起設置。 例:

    spring.jpa.properties.hibernate.globally_quoted_identifiers=true

    將hibernate.globally_quoted_identifiers 傳遞給Hibernate實體管理器。

    默認情況下,DDL執行(或驗證)將延遲到ApplicationContext啟動。 還有一個spring.jpa.generate-ddl標志,但是如果Hibernate 自動配置是激活的,那么它將不會被使用,因為ddl-auto配置更好。

    29.3.4 在View中打開EntityManager

    如果您正在運行Web應用程序,Spring Boot將默認注冊OpenEntityManagerInViewInterceptor來應用“查看”中的“打開EntityManager”模式,即允許在Web視圖中進行延遲加載。 如果你不想要這個行為,你應該在你的application.properties中將spring.jpa.open-in-view設置為false。

    29.4 使用H2的Web控制臺

    H2數據庫提供了一個基于瀏覽器的控制臺,Spring Boot可以為您自動配置。 滿足以下條件時,控制臺將自動配置:

    • 您正在開發一個Web應用程序
    • com.h2database:h2在類路徑上
    • 您正在使用Spring Boot的開發者工具

    如果您不使用Spring Boot的開發人員工具,但仍希望使用H2的控制臺,那么可以通過配置一個值為true的spring.h2.console.enabled屬性來實現。 H2控制臺僅用于開發期間,因此應注意確保spring.h2.console.enabled在生產中未設置為true。

    29.4.1 更改H2控制臺的路徑

    默認情況下,控制臺路徑將在 /h2-console上。 您可以使用spring.h2.console.path屬性來自定義控制臺的路徑。

    29.4.2 保護H2控制臺

    當Spring Security位于類路徑上且啟用了基本身份驗證時,H2控制臺將自動使用基本身份驗證進行保護。 以下屬性可用于自定義安全配置:

    • security.user.role
    • security.basic.authorize-mode
    • security.basic.enabled

    29.5 使用jOOQ

    Java面向對象查詢(jOOQ)是Data Geekery的產品,它從數據庫生成Java代碼,并通過流暢的API構建類型安全的SQL查詢。 商業版和開源版都可以與Spring Boot一起使用。

    29.5.1 代碼生成

    為了使用jOOQ類型安全的查詢,您需要從數據庫模式生成Java類。 您可以按照jOOQ用戶手冊中的說明進行操作。 如果您正在使用jooq-codegen-maven插件(并且還使用spring-boot-starter-parent“父POM”),您可以安全地省略插件的<version>標簽。 您還可以使用Spring Boot定義的版本變量(例如h2.version)來聲明插件的數據庫依賴關系。 以下是一個例子:

    <plugin><groupId>org.jooq</groupId><artifactId>jooq-codegen-maven</artifactId><executions>...</executions><dependencies><dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><version>${h2.version}</version></dependency></dependencies><configuration><jdbc><driver>org.h2.Driver</driver><url>jdbc:h2:~/yourdatabase</url></jdbc><generator>...</generator></configuration> </plugin>

    29.5.2 使用 DSLContext

    jOOQ提供的流暢的API是通過org.jooq.DSLContext接口啟動的。 Spring Boot將自動配置DSLContext作為Spring Bean并將其連接到應用程序DataSource。 要使用DSLContext,您只需@Autowire它:

    @Component public class JooqExample implements CommandLineRunner { <span class="hljs-keyword">private</span> <span class="hljs-keyword">final</span> DSLContext create;<span class="hljs-meta">@Autowired</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">JooqExample</span><span class="hljs-params">(DSLContext dslContext)</span> </span>{<span class="hljs-keyword">this</span>.create = dslContext; }

    }

    jOOQ手冊傾向于使用名為create的變量來保存DSLContext,我們在此示例中也是這樣。

    然后,您可以使用DSLContext構建查詢:

    public List<GregorianCalendar> authorsBornAfter1980() {return this.create.selectFrom(AUTHOR).where(AUTHOR.DATE_OF_BIRTH.greaterThan(new GregorianCalendar(1980, 0, 1))).fetch(AUTHOR.DATE_OF_BIRTH); }

    29.5.3 定制jOOQ

    您可以通過在application.properties中設置spring.jooq.sql-dialect來自定義jOOQ使用的SQL方言。 例如,要指定Postgres,您可以添加:

    spring.jooq.sql-dialect=Postgres

    通過定義自己的@Bean定義可以實現更高級的定制,這些定義將在創建jOOQ配置時使用。您可以為以下jOOQ類型定義bean:

    • ConnectionProvider
    • TransactionProvider
    • RecordMapperProvider
    • RecordListenerProvider
    • ExecuteListenerProvider
    • VisitListenerProvider

    如果要完全控制jOOQ配置,您還可以創建自己的org.jooq.Configuration @Bean。

    30. 使用NoSQL技術

    Spring Data提供了額外的項目,可幫助您訪問各種NoSQL技術,包括MongoDB,Neo4J,Elasticsearch,Solr,Redis,Gemfire,Cassandra,Couchbase和LDAP。 Spring Boot為Redis,MongoDB,Neo4j,Elasticsearch,Solr Cassandra,Couchbase和LDAP提供了自動配置; 您也可以使用其他項目,但您需要自行配置它們。 請參閱projects.spring.io/spring-data中相應的參考文檔。

    30.1 Redis

    Redis是一個緩存,消息代理并有功能豐富的鍵值存儲數據庫。Spring Boot提供了Jedis客戶端庫的基本自動配置和Spring Data Redis提供的抽象。 有一個spring-boot-starter-data-redis“Starter”用于以方便的方式收集依賴關系。

    30.1.1 連接到Redis

    您可以像任何其他Spring Bean一樣注入自動配置的RedisConnectionFactory,StringRedisTemplate或vanilla RedisTemplate實例。 默認情況下,實例將嘗試使用localhost:6379連接到Redis服務器:

    @Component public class MyBean { <span class="hljs-keyword">private</span> StringRedisTemplate template;<span class="hljs-meta">@Autowired</span> <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">MyBean</span><span class="hljs-params">(StringRedisTemplate template)</span> </span>{<span class="hljs-keyword">this</span>.template = template; }<span class="hljs-comment">// ...</span>

    }

    如果您添加了您自己的任何自動配置類型的@Bean,它將替換默認值(除了在RedisTemplate的情況下,排除是基于bean名稱“redisTemplate”而不是其類型)。 如果commons-pool2在類路徑上,則默認情況下將獲得一個pooled連接工廠。

    30.2 MongoDB

    MongoDB是一個開源的NoSQL文檔數據庫,它使用類似JSON的架構,而不是傳統的基于表的關系數據。 Spring Boot為MongoDB提供了幾種便利,包括spring-boot-starter-data-mongodb'Starter'。

    》》》博主長期更新學習心得,推薦點贊關注!!!
    》》》若有錯誤之處,請在評論區留言,謝謝!!!

    總結

    以上是生活随笔為你收集整理的Spring Boot 1.5.2.RELEASE中文版的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    午夜精品视频一区 | 91欧美视频网站 | 免费a视频 | 日韩在线观看高清 | 国产精品美 | 久久久在线 | 亚洲亚洲精品在线观看 | 五月婷婷.com | 最近2019中文免费高清视频观看www99 | 久久久久久久久免费 | 欧洲精品亚洲精品 | 91精品在线免费 | 日本xxxx.com | 99久久99视频 | 国产在线播放观看 | 久青草国产在线 | 国产精品麻豆欧美日韩ww | 青草视频在线 | 奇米777777| 成人亚洲精品国产www | 激情欧美一区二区三区免费看 | 在线观看免费高清视频大全追剧 | 亚洲综合在线一区二区三区 | 国产精品丝袜 | 2020天天干天天操 | 色中色综合 | 7777精品伊人久久久大香线蕉 | 在线中文字幕网站 | 天天爱综合| 国产免费作爱视频 | 国产在线理论片 | 91av在线电影| 91精品国产99久久久久久久 | 91久久久久久久一区二区 | 2022久久国产露脸精品国产 | 国产一区二区在线观看视频 | 亚洲欧洲视频 | 久久99久久99精品中文字幕 | 亚洲高清视频在线 | 国产成人亚洲精品自产在线 | 91av社区 | 欧美另类性 | 99人成在线观看视频 | 久久不卡国产精品一区二区 | 亚洲女裸体 | 国产精品手机视频 | 在线观看免费一区 | 97超视频| 91久久奴性调教 | 色噜噜日韩精品一区二区三区视频 | 色综合天天综合 | 一区二区三区四区精品 | 在线国产高清 | 一区二区中文字幕在线播放 | 久久亚洲影院 | 久久久久久久久久影院 | 久久国产精品免费 | 日本爱爱免费视频 | 香蕉在线视频播放网站 | 四虎永久免费在线观看 | 国产精品欧美久久久久天天影视 | 精品夜夜嗨av一区二区三区 | 免费一级特黄毛大片 | 欧美色图30p | 一区二区视频欧美 | 精品一二三区视频 | 日日插日日干 | 日本狠狠干| 日韩一级黄色大片 | 亚洲精品在线免费 | 国产成人av片 | 福利网在线 | 午夜国产福利在线 | 国产成人av免费在线观看 | 精品在线观看视频 | 成人午夜网 | 91九色porny在线 | 国产黄色免费观看 | 91大神dom调教在线观看 | 五月婷婷毛片 | 黄色app网站在线观看 | 99精品热| 69中文字幕 | 久草在线费播放视频 | 超碰在线人人爱 | 午夜视频播放 | 在线视频精品播放 | 久草在线| 永久免费精品视频网站 | sesese图片| 欧美视频国产视频 | www.黄色在线 | 日韩精品一区二区三区免费观看视频 | 免费a网址| 国产精品美女毛片真酒店 | 亚洲高清精品在线 | 九九热视频在线 | 亚洲一级片免费观看 | 人人干在线观看 | 91视频最新网址 | 99国产一区二区三精品乱码 | 丁香花五月 | 在线视频第一页 | 亚洲黄色在线观看 | 成人黄色视 | 中文字幕国产视频 | 中文字幕免费在线 | 五月天,com| 日韩在观看线 | 蜜桃av久久久亚洲精品 | 一区二区三区高清不卡 | 色欧美日韩 | 超碰免费观看 | 国产资源在线观看 | 午夜精品久久久久久久久久久久久久 | 特级毛片在线免费观看 | 午夜精品视频免费在线观看 | 黄色av成人在线观看 | 精品一二三四五区 | 国产视频一区二区在线观看 | 国产成人av福利 | 国产精品高清在线 | 中文字幕精品一区二区三区电影 | 国产精品一区二区久久国产 | 精品五月天 | 国产1级视频| 日韩欧美综合视频 | 日韩v在线 | 999久久久久久 | 国产无遮挡猛进猛出免费软件 | 四虎在线永久免费观看 | 久久久久久高清 | 99综合视频 | 日韩网站中文字幕 | 92精品国产成人观看免费 | 在线观看中文字幕亚洲 | 亚洲一级片免费观看 | 最新黄色av网址 | 亚洲欧洲精品视频 | 久精品视频免费观看2 | 国产免费不卡 | 四虎国产精品免费观看视频优播 | www.com久久| 在线观看黄网站 | 在线观看视频一区二区三区 | 射久久久 | 中文字幕超清在线免费 | 婷婷综合亚洲 | 日韩欧美视频 | 午夜国产福利在线 | 超碰在线人人 | 超碰97网站 | 999国内精品永久免费视频 | 国产精品午夜久久久久久99热 | 美腿丝袜av | 麻花豆传媒mv在线观看网站 | 欧美精品一区二区在线观看 | 777xxx欧美 | 亚洲 中文字幕av | 91成人免费在线视频 | 黄色毛片电影 | 香蕉视频网站在线观看 | 色wwww| 久久精品久久精品久久 | 日韩首页 | 久草在线视频网站 | 国产成人精品久久久 | 九九色网 | 国产精品久久久久久久久久 | 青草视频免费观看 | 国产视频亚洲视频 | 精品免费观看 | 成人久久视频 | 精品国产欧美一区二区 | 亚洲人成在线观看 | 啪一啪在线| 天天看天天干天天操 | 国内丰满少妇猛烈精品播 | 天天爱天天干天天爽 | 国产精品久久久久一区二区三区 | 国产黄色在线看 | 少妇高潮冒白浆 | 日韩av网页| 波多野结衣在线视频一区 | 亚洲精品videossex少妇 | 久久av中文字幕片 | 91污在线 | 日本字幕网 | 最近免费中文字幕 | 国产xxxx性hd极品 | av福利在线 | 久久成人国产精品免费软件 | 婷婷爱五月天 | 中文字幕高清免费日韩视频在线 | 久草在线费播放视频 | 亚洲va天堂va欧美ⅴa在线 | 精品国产大片 | 久久精品一二区 | 成人免费xxx在线观看 | 午夜三级大片 | 久久综合给合久久狠狠色 | 91三级视频| 亚洲精品字幕在线 | 亚洲欧美视频网站 | 亚州国产精品久久久 | 国产九九在线 | 国产精品www | 国产精品96久久久久久吹潮 | 国产精品国产亚洲精品看不卡15 | 亚洲爱爱视频 | 国产精品毛片 | 四虎在线永久免费观看 | 免费在线激情电影 | 国产精品久久久久久久久久久久 | 欧美日韩不卡在线视频 | 五月天久久婷婷 | 日韩羞羞 | a在线播放 | 中文字幕在线看视频国产 | 激情久久一区二区三区 | 天天干天天操天天做 | 伊人六月| 97电影网站 | 91自拍视频在线观看 | 激情欧美丁香 | 日韩高清一 | 夜夜躁狠狠躁日日躁视频黑人 | av一级网站| 美女网站黄免费 | 久久久久夜色 | 91中文字幕视频 | 国产不卡在线观看视频 | 中文字幕av在线 | 二区三区毛片 | 欧美日韩精品影院 | 日日夜夜综合网 | 夜色资源站国产www在线视频 | 亚洲国产精品va在线看黑人 | 久久精品亚洲精品国产欧美 | 伊人色**天天综合婷婷 | 久久99精品国产99久久6尤 | aav在线| 91精品国产成人www | 808电影免费观看三年 | 五月天久久婷婷 | 黄色免费观看视频 | 久久免费视频网站 | 国产99自拍 | 国产91粉嫩白浆在线观看 | 亚洲精品系列 | 成人少妇影院yyyy | www.色综合.com | 91精品久久久久久粉嫩 | 99精品在线直播 | 911精品美国片911久久久 | 91大神一区二区三区 | 99视频在线观看一区三区 | 88av视频 | 日韩免费不卡av | 天堂网一区 | 在线成人免费av | 亚洲涩涩网 | 亚洲精品裸体 | 丁香五月亚洲综合在线 | 久章草在线观看 | 欧美日韩不卡在线 | 成人免费xyz网站 | 天天搞天天 | 久久人人爽视频 | 国产精品久久久久久爽爽爽 | 黄色网在线播放 | 69久久久久久久 | 日日综合 | 国产欧美综合视频 | 久久精品国产一区二区三区 | 国产明星视频三级a三级点| 综合精品久久 | 中文字幕在线看视频国产中文版 | 91亚色视频在线观看 | 欧美 另类 交 | 日韩欧美在线高清 | 激情网站 | 精品久久久久国产免费第一页 | 91av网站在线观看 | 夜夜夜影院 | 国产精品美女久久久久久久久久久 | 热久久免费国产视频 | 天天操天天色天天 | 久久久久久国产精品免费 | 亚洲精品玖玖玖av在线看 | 国产精品大全 | 免费成人av在线 | 免费看特级毛片 | 亚洲综合在线观看视频 | 欧美a免费| 欧美一区二区在线看 | 99亚洲国产精品 | 91精品久久久久久久91蜜桃 | 午夜精品久久久久 | 亚洲 欧美 综合 在线 精品 | 五月综合激情网 | 欧美色道 | 激情婷婷亚洲 | 久久国产亚洲精品 | 久久av高清| 在线视频日韩精品 | 亚洲国产精品一区二区久久,亚洲午夜 | 啪啪免费观看网站 | 天天操天天操天天操 | 久久精品视频在线观看 | 97日日碰人人模人人澡分享吧 | 国产最新在线观看 | 婷婷色5月 | 91chinese在线 | 九九热视频在线免费观看 | 亚洲一区二区三区91 | 欧美午夜久久久 | 91久久国产露脸精品国产闺蜜 | 久久综合久久鬼 | 久久久国产精品一区二区中文 | 久久久久久久久久久黄色 | 日本乱视频 | 九九热re | 中文字幕在线观看完整版电影 | 日韩av进入| 久久伊人婷婷 | 91av视屏| 日韩电影在线一区 | 又黄又爽的免费高潮视频 | 成人91在线观看 | www激情com| 欧美国产在线看 | 国产一区二区在线影院 | 超碰97人人射妻 | 国产精品手机在线观看 | 91人人插| 国产精品毛片一区视频播不卡 | 在线免费观看的av网站 | 在线免费色视频 | 91av在线视频播放 | 在线播放国产精品 | 国产精品h在线观看 | 午夜.dj高清免费观看视频 | 亚洲精品大全 | 在线免费亚洲 | 免费观看一级一片 | 婷婷六月在线 | 欧洲精品视频一区 | 亚洲一区二区三区四区在线视频 | 国产免费人人看 | 久久婷婷精品 | 成人国产亚洲 | 日本精品视频在线观看 | 久久久一本精品99久久精品66 | 成人在线播放视频 | 久久亚洲区 | 久久精品视频播放 | 天天干天天碰 | 国产又粗又猛又黄又爽视频 | 九九九视频在线 | 一区二区三区在线播放 | 99高清视频有精品视频 | 亚洲精品乱码久久久久久久久久 | 国产精品毛片一区二区三区 | 亚洲人人射 | 久久特级毛片 | 国产成人久久精品77777 | 国产日产av | 99国产精品视频免费观看一公开 | 久草视频看看 | 91网站观看 | 国产中文字幕在线看 | 日韩精品高清视频 | 久久这里只有精品视频99 | 日韩在线视频在线观看 | 亚洲欧美日韩国产一区二区三区 | 超碰人人超碰 | 国产精品夜夜夜一区二区三区尤 | 高清国产午夜精品久久久久久 | 99色 | 国产综合视频在线观看 | 中文字幕免费高清 | 欧美午夜久久 | 91福利区一区二区三区 | 91精品啪在线观看国产线免费 | 久久免费中文视频 | 黄色三级在线看 | 色99色| 综合精品久久久 | 一区二区三区影院 | 中文日韩在线视频 | 伊人久久婷婷 | 中文字幕一区2区3区 | 97精品国产97久久久久久 | 亚洲国产中文字幕在线观看 | 最近日韩免费视频 | 激情五月六月婷婷 | 天天干.com| 国产黄色片一级三级 | 99热九九这里只有精品10 | 久久国产精品99国产 | 欧美永久视频 | 久久一区二区三区日韩 | 黄色aaa级片 | 欧美一级免费在线 | 99视频国产精品免费观看 | 一区二区三区四区免费视频 | 在线91精品 | 亚洲欧洲精品久久 | 日日夜夜免费精品视频 | 国产96在线观看 | 天天爱天天射天天干天天 | 国产黄色观看 | 青青河边草手机免费 | 欧美一级片播放 | 精品久久一| 日韩av一区二区三区四区 | 在线免费av观看 | 精品久久久久国产 | 99夜色| 国产黄a三级三级三级三级三级 | 日本久久久久久久久久久 | 免费日韩 精品中文字幕视频在线 | 爱爱av网站 | 五月婷婷影院 | 久久99精品久久久久久 | 91中文视频 | 黄污在线观看 | 丁香花在线观看免费完整版视频 | 国产亚洲午夜高清国产拍精品 | 在线日韩av | 99热这里只有精品免费 | 91成人免费看 | 激情久久五月天 | 2019中文在线观看 | 国产精品一区二区三区四区在线观看 | 91丨九色丨国产丨porny精品 | 日韩欧美在线观看 | 人人添人人澡 | 欧美人人 | 久草97| 国产精品入口麻豆www | 蜜桃视频在线视频 | 亚洲欧美视频在线播放 | 91手机电视 | 黄色国产精品 | 操操操人人人 | 亚洲深爱激情 | 国产日产精品一区二区三区四区 | 一区二区三区在线不卡 | 国产超碰97 | 国产成人综合图片 | 91视频在线免费下载 | 久久精品第一页 | 久久99热这里只有精品 | 一区二区电影网 | 最新日本中文字幕 | 91精品黄色| 国产 欧美 日产久久 | 丰满少妇一级片 | 成人av在线影院 | 少妇bbbb| 日韩免费中文 | www.一区二区三区 | 91人人澡人人爽人人精品 | 欧美影院久久 | 黄污视频网站大全 | 日本高清dvd | 精品视频在线观看 | 91福利影院在线观看 | 国产精品系列在线播放 | 国产精品青草综合久久久久99 | 亚洲国产视频直播 | 伊人黄| 最近中文字幕视频网 | 在线www色 | 黄色在线观看免费网站 | 激情五月婷婷 | 99精品欧美一区二区蜜桃免费 | 免费日韩 精品中文字幕视频在线 | 麻豆视频成人 | 西西444www大胆高清图片 | 深爱激情久久 | 国产中的精品av小宝探花 | 免费观看国产精品 | 国产伦理剧 | 国产成人免费观看久久久 | 久久综合激情 | 中文字幕在线一区二区三区 | 亚洲精品mv在线观看 | 久草在线这里只有精品 | 99爱爱 | 成人在线视频观看 | 香蕉视频国产在线观看 | 日韩成人免费在线 | 中文字幕在线观看网站 | 国产精品密入口果冻 | 在线看小早川怜子av | 日韩免费一区 | 亚洲精品久久激情国产片 | 国产精品爽爽爽 | 久久av中文字幕片 | 欧美va日韩va| 亚洲精品66| 福利一区视频 | 亚洲无人区小视频 | 久久国产精品99久久久久久进口 | 亚洲永久av | 色停停五月天 | 国产成年免费视频 | 人人爱爱人人 | 日韩毛片在线一区二区毛片 | 亚洲综合激情小说 | 欧美在线不卡一区 | 成人va在线观看 | 精品国产91亚洲一区二区三区www | 久久久91精品国产一区二区三区 | 欧美激情视频免费看 | 久草在线免费看视频 | 国产男女爽爽爽免费视频 | 免费特级黄毛片 | 色婷婷激情综合 | 日本中文字幕在线看 | 热久久最新地址 | 超碰在线天天 | 日韩欧美高清一区二区三区 | 欧美一区二区三区免费观看 | 国产裸体无遮挡 | av在线进入 | 国产福利91精品一区 | 国产免费观看久久 | 正在播放国产91 | www激情网 | 米奇狠狠狠888 | 国产精品理论在线观看 | 国产美女视频黄a视频免费 久久综合九色欧美综合狠狠 | 国产精品综合久久久久 | 日韩网站中文字幕 | 一区二区三区日韩精品 | 久久综合色婷婷 | 婷婷午夜 | 五月婷在线视频 | 亚洲免费在线观看视频 | 久久丁香 | 色噜噜狠狠狠狠色综合 | 天天色天天爱天天射综合 | 国产午夜在线观看视频 | 激情狠狠干 | 国产中文在线视频 | 亚洲aⅴ一区二区三区 | 久久久香蕉视频 | 久久人人爽人人爽人人片av软件 | 亚洲国产精品资源 | 特级西西444www大胆高清无视频 | 色婷婷导航 | 一区二区三区视频在线 | 香蕉影院在线观看 | 日本69hd | 亚洲最大免费成人网 | 欧美a级在线 | 国产视频综合在线 | 国产黄色在线观看 | 日韩有码网站 | 日韩av片无码一区二区不卡电影 | 丁五月婷婷 | 国产精品女主播一区二区三区 | 欧美国产三区 | 日韩啪啪小视频 | www.香蕉视频| 88av视频| 手机av电影在线观看 | 久久精品亚洲 | 国产精品一区二区麻豆 | 爱射综合 | 成人av电影在线播放 | 日本中文字幕在线观看 | 亚洲精品国偷自产在线91正片 | 欧美精品xx | 我要看黄色一级片 | 99视频这里只有 | 欧美成人黄 | 日本aaaa级毛片在线看 | 色婷婷骚婷婷 | 久久人91精品久久久久久不卡 | 天天草天天爽 | 男女视频久久久 | 超碰97在线资源 | 国产成人1区| 色欧美88888久久久久久影院 | 国产91免费观看 | 国产又粗又硬又长又爽的视频 | 91九色蝌蚪国产 | 在线视频欧美日韩 | 91在线观看黄 | 国产精品久99 | 国产精品久久久久久久久大全 | 久久人人爽爽 | 国产精品女同一区二区三区久久夜 | 国产精品va在线观看入 | 久视频在线播放 | 亚洲女欲精品久久久久久久18 | 久久久久99精品成人片三人毛片 | 国产精品久久艹 | 国产精品视频区 | 欧美日韩视频在线观看免费 | 天天插日日插 | 亚洲成免费| a视频在线观看免费 | 国产麻豆成人传媒免费观看 | 国产一级免费观看视频 | 91大神电影 | 国产精品一区二区av麻豆 | 国产69精品久久app免费版 | 国产精品麻豆一区二区三区 | 91传媒激情理伦片 | 黄色录像av | 欧美精彩视频在线观看 | 欧美日韩免费观看一区二区三区 | 在线视频 一区二区 | 久久超级碰视频 | 99精品在线观看 | 国模一二三区 | 在线观看免费色 | 欧美日韩亚洲国产一区 | 97在线观看免费观看高清 | 久久久久久久久艹 | 天天操天天综合网 | 亚洲精品美女在线观看 | 欧美 日韩 成人 | 免费在线a | 国产第一福利网 | 日韩首页 | 99热这里 | 久久国产精品一区二区三区 | 97自拍超碰| 免费看网站在线 | 中文免费 | 国产尤物在线 | 婷婷在线综合 | 色com | 99精品久久精品一区二区 | 国产在线观看一 | 精品福利在线视频 | 99久久精品久久亚洲精品 | 另类老妇性bbwbbw高清 | 国产精品99久久久精品 | 最近中文字幕在线播放 | 欧美视频99 | 一区免费在线 | 中文视频在线播放 | 狠狠色丁婷婷日日 | 麻豆91网站 | 久久精品精品电影网 | 91视频在线免费 | 亚洲欧洲成人 | 精品国产一区二区三区日日嗨 | 天天操天天色天天射 | 国产精品视频区 | 国产精品综合久久久久 | 国产福利91精品一区二区三区 | 成人国产精品电影 | 天天综合网久久综合网 | 国产香蕉97碰碰久久人人 | 国产香蕉97碰碰久久人人 | 国产在线观看免 | 欧美日韩精品在线视频 | 精品国产视频在线观看 | 欧美久草视频 | 毛片网免费| 免费高清在线视频一区· | 亚洲国产精品女人久久久 | 欧美成人69av| av+在线播放在线播放 | 国产精品专区h在线观看 | 天天干亚洲 | 国产精品国产三级国产不产一地 | 五月视频 | 久久久久久久久久久福利 | 国内精品久久久久久中文字幕 | 日韩欧美视频一区二区三区 | 精品国产伦一区二区三区免费 | 99麻豆视频| 99电影456麻豆 | 91精品国产91 | 久久高视频 | 美女av在线免费 | 国产在线不卡 | 手机成人在线电影 | 一级黄色片毛片 | 精品视频久久久 | 四虎成人精品永久免费av | 免费视频91蜜桃 | 一区二区三区在线免费播放 | 日本久久成人中文字幕电影 | 欧美成人黄色片 | 久久r精品 | 久久久精选 | 国产精品久久久av久久久 | 国产精品久久毛片 | 久久免费的视频 | 91禁在线看 | 国产韩国日本高清视频 | 在线超碰av| 国产精品资源在线 | 在线精品在线 | 欧美国产一区二区 | 色综合天天色综合 | 国产高h视频 | 免费黄色在线网站 | 免费在线观看国产黄 | 久久视频免费在线 | 女女av在线 | 国产乱对白刺激视频不卡 | 欧美精品一区二区在线观看 | 国产又粗又猛又色 | 久久综合九色九九 | 美女久久久久久久 | 午夜色站 | 一级免费看| 深夜免费福利视频 | 中文字幕大全 | 国产精品一区二区av | 免费99精品国产自在在线 | 欧美激情综合网 | 久久精品一二三区白丝高潮 | 波多在线视频 | 亚洲在线网址 | 超碰com| 午夜视频欧美 | 91色在线观看视频 | 欧美 亚洲 另类 激情 另类 | 91视频在线网址 | 国产美女精品视频 | 国产区久久 | 狠狠色丁香久久婷婷综合五月 | 亚洲国产视频a | 天天干亚洲 | 四虎影视欧美 | 久久99久久99精品免视看婷婷 | 国产成人精品一区在线 | 一区二区不卡高清 | 在线观看日韩免费视频 | 国产免费又黄又爽 | 天天干国产| 黄色影院在线观看 | 久久久久婷 | 麻豆传媒视频在线 | 成人a毛片 | 亚洲欧美视频在线 | 国产成人精品一区二三区 | av免费在线观看网站 | 日韩免费在线一区 | 久久综合中文色婷婷 | 伊人狠狠操 | 在线中文字幕一区二区 | 国产又粗又长的视频 | 久久久久在线 | 久久婷婷色 | 久久99影院| 亚洲欧美国产精品va在线观看 | 午夜久久精品 | 色综合色综合色综合 | 欧美日韩精品在线一区二区 | 精品一区二区影视 | 精品国产色 | 成人av免费在线看 | 国产资源免费 | 色av资源网| 91精品国产高清自在线观看 | 免费热情视频 | 久草在线看片 | wwwwww国产| 国产精品美女久久久久久久久久久 | 日日夜夜91 | 女人高潮一级片 | 黄色片网站av | 国产午夜不卡 | 中文字幕在线久一本久 | 国产91在线观 | 亚洲一区免费在线 | 手机在线免费av | 亚洲视频一区二区三区在线观看 | 国产精品地址 | 欧美一级高清片 | 在线观看国产www | 中文十次啦 | 久久久高清一区二区三区 | 天天干天天操天天拍 | 日韩区欠美精品av视频 | 久久久久电影网站 | 国产成人精品电影久久久 | 免费午夜视频在线观看 | 中文字幕精品www乱入免费视频 | 91亚洲精品久久久中文字幕 | 久草网在线视频 | 日日夜夜精品免费观看 | 91av在线精品 | 在线一二三区 | 在线看黄色的网站 | 久久国产精品99国产 | 91尤物国产尤物福利在线播放 | 超碰国产在线观看 | 成人永久在线 | 亚洲综合欧美精品电影 | 免费在线观看一区二区三区 | av天天色 | 深夜免费小视频 | 国产精品视频免费 | 在线不卡中文字幕播放 | 国产爽视频 | 欧美色婷婷 | 日本一区二区不卡高清 | 91精品国自产拍天天拍 | 热热热热热色 | 成年人在线视频观看 | 亚洲激情婷婷 | 最新国产精品拍自在线播放 | 手机在线黄色网址 | 三级av免费 | 综合网婷婷 | 久久97超碰 | 欧美在线视频一区二区三区 | 九色91在线视频 | 日本精品视频在线播放 | 国产精品久久久久久久久久不蜜月 | 国产无套精品久久久久久 | 国产精品欧美久久 | 在线视频 一区二区 | 九九九视频在线 | 色美女在线 | 99精品视频一区二区 | 精品国模一区二区三区 | 中文字幕乱码一区二区 | 久久精品精品电影网 | 欧美日韩国产页 | 日日干综合 | 国产精品一区二区电影 | av中文天堂在线 | 亚洲免费精彩视频 | 91av精品| 激情五月婷婷激情 | 欧美一级日韩三级 | 日韩在线视| 99久久久国产精品美女 | 国产精品国产自产拍高清av | 一区二区三区免费在线观看视频 | 久久久久亚洲精品 | 免费观看一级一片 | 521色香蕉网站在线观看 | 欧美激情操 | 欧美日韩一区二区三区在线免费观看 | 亚洲欧洲av | 欧美性护士 | 天天草天天摸 | 91黄色在线视频 | 麻豆传媒视频在线免费观看 | 美女视频免费一区二区 | 国产视频网站在线观看 | 蜜桃视频在线观看一区 | 中文字幕亚洲高清 | 国产午夜在线观看视频 | 激情综合网色播五月 | 国产精品99页| 亚洲日本欧美在线 | 亚洲一级电影视频 | 久99久精品 | 日韩av电影免费在线观看 | av黄色影院| 九九免费精品 | 亚洲精品乱码久久久久久写真 | 人人爽人人澡人人添人人人人 | 91在线公开视频 | 欧美日韩精品在线观看 | 操操操人人人 | 最近中文字幕视频完整版 | 久久国产精品视频观看 | 国产白浆视频 | 国产精品成人av在线 | 久久电影中文字幕视频 | 能在线看的av| 一级一片免费观看 | 欧美日韩一区二区三区在线免费观看 | 精品在线视频一区二区三区 | 免费精品久久久 | 久草网视频 | 天天天天天天天操 | 精品视频在线播放 | 果冻av在线| 欧美精品久久久久久 | 91视频链接 | 五月激情六月丁香 | 狠狠色香婷婷久久亚洲精品 | 日韩在线视频一区二区三区 | 青春草免费视频 | 国产精品久久久久国产精品日日 | 欧洲在线免费视频 | 99草视频| 九色福利视频 | 国产一区成人 | 色狠狠干 | 欧美激情精品一区 | 午夜精品久久一牛影视 | 国产在线2020 | 亚洲精品 在线视频 | 国内精品久久天天躁人人爽 | 欧美91精品久久久久国产性生爱 | 欧美精品v国产精品 | 国产精品一区二区三区四区在线观看 | 日韩欧美视频免费观看 | 久久久精品视频成人 | 亚洲欧美激情插 | 国产尤物视频在线 | 草久久影院 | 伊人影院99 | 国产精品久久久久久久久久新婚 | 久久天天躁狠狠躁夜夜不卡公司 | 片网址| 天天插综合网 | 中文字幕资源在线观看 | 日本中文字幕在线视频 | 国产中文字幕三区 | 婷婷激情五月综合 | 久草视频在 | 亚洲第一av在线 | 成年人免费在线看 | 欧美成人在线免费 | 久久99亚洲精品久久久久 | 四虎天堂 | 免费观看xxxx9999片 | 久久精品一区 | 亚洲理论片在线观看 | 青青看片 | 欧美黑人猛交 | 日韩精品一区二区免费视频 | 一区二区三区韩国免费中文网站 | 四虎5151久久欧美毛片 | 久久精品99国产精品日本 | 久久伊人国产精品 | 精品日韩中文字幕 | 国产中文字幕视频 | avove黑丝| 免费亚洲一区二区 | 久久99久久99精品免观看软件 | 国产一级电影在线 | a在线播放| 在线免费视频你懂的 | 成人av在线直播 | 日韩久久午夜一级啪啪 | 97在线视频免费看 | 99av国产精品欲麻豆 | 粉嫩一二三区 | 国产成人精品999 | 在线观av | 国产自偷自拍 | 欧美日韩免费观看一区二区三区 | 精品免费视频123区 午夜久久成人 | 婷婷精品在线视频 | 成年人免费观看在线视频 | 国产成人精品一区二区三区福利 | 丁香婷婷色综合亚洲电影 | 国产亚洲精品美女 | 久久人人爽人人 | 免费色网 | 最近日本中文字幕 | 日韩精品电影在线播放 | 在线免费高清一区二区三区 | 视频在线观看日韩 | 一级黄色片在线免费观看 | 在线观看免费一区 | 精品久久网站 | 国产美女无遮挡永久免费 | 国产精品一区二区三区免费视频 | 五月天激情视频在线观看 | 在线精品亚洲 | 国产aa精品| 国产97在线观看 | 三级黄色大片在线观看 | 精品一二三区 | 在线亚洲精品 | 一级国产视频 | 在线视频麻豆 | 精品中文字幕在线观看 | 国产视频1区2区3区 久久夜视频 | 成 人 黄 色 视频免费播放 | 麻豆国产电影 | 亚洲一区二区麻豆 | 日日草天天草 | 亚洲理论在线 | 久久综合毛片 | 日韩精品无 | 色综合综合| 国产999精品久久久影片官网 | 婷婷在线色| 手机av电影在线 | 丁香六月伊人 | 美女网站视频免费黄 | 久久精品国产v日韩v亚洲 | 一区二区三区电影 |