日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

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

javascript

Spring Boot 1.5.2.RELEASE中文版

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

Spring Boot 1.5.2.RELEASE中文版

Part I. Spring Boot 文檔

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

1. 關于文檔

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

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

2. 獲得幫助

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

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

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

3. 第一步

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

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

4. 使用 Spring Boot

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

5. 了解Spring Boot功能

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

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

6. 轉移到生產環(huán)境

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

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

Part II. 入門指南

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

8. Spring Boot 介紹

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

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

我們的主要目標是:

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

9. 系統(tǒng)要求

默認情況下,Spring Boot 1.5.2.RELEASE需要Java 7和Spring Framework 4.3.7.RELEASE或更高版本。 您可以進行一些其他配置在Java 6上使用Spring Boot。 有關詳細信息,請參見第84.11節(jié)“如何使用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開發(fā)工具一起使用或作為命令行工具安裝。 無論如何,您將需要Java SDK v1.6或更高版本。 在開始之前檢查當前的Java安裝:

$ java -version

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

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

10.1 針對Java開發(fā)程序員安裝說明

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

10.1.1 Maven安裝

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

在許多操作系統(tǒng)上,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插件來創(chuàng)建可執(zhí)行的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節(jié)“使用不帶父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插件,可用于簡化依賴關系聲明和創(chuàng)建可執(zhí)行 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發(fā)行版:

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

各發(fā)布版本的快照。

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

10.2.2 使用SDKMAN!安裝

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

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

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

$ 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),您的安裝可能會過期。 只需執(zhí)行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),或將其放在您的個人或系統(tǒng)范圍的bash完成初始化中。 在Debian系統(tǒng)上,系統(tǒng)范圍的腳本位于 /shell-completion/bash 中,當新的shell啟動時,該目錄中的所有腳本將被執(zhí)行。 手動運行腳本,例如 如果您使用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應用程序,可用于測試您的安裝是否正確。 創(chuàng)建一個名為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

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

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

Hello World!

10.3 從早期版本的Spring Boot升級

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

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

11. 開發(fā)您的第一個Spring Boot應用程序

讓我們在Java中開發(fā)一個簡單的“Hello World!”Web應用程序,突顯Spring Boot一些主要的功能。 我們將使用Maven構建該項目,因為大多數(shù)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

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

11.1 創(chuàng)建POM

我們需要先創(chuàng)建一個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!”)。

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

11.2 添加類路徑依賴關系

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

其他“啟動器(Starters)”只是提供您在開發(fā)特定類型的應用程序時可能需要的依賴關系。 由于我們正在開發(fā)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 ,您將看到現(xiàn)在有許多附加依賴關系,包括Tomcat Web服務器和Spring Boot本身。

11.3 編寫代碼

要完成我們的應用程序,我們需要創(chuàng)建一個的Java文件。 默認情況下,Maven將從src/main/java編譯源代碼,因此您需要創(chuàng)建該文件夾結構,然后添加一個名為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 根據(jù)您添加的jar依賴關系來“猜(guess)”你將如何配置Spring。由于spring-boot-starter-web添加了Tomcat和Spring MVC,自動配置將假定您正在開發(fā)Web應用程序并相應地配置Spring。

啟動器和自動配置

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

11.3.3 “main”方法

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

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 創(chuàng)建可執(zhí)行的jar

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

可執(zhí)行jar和Java

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

要創(chuàng)建可執(zhí)行的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重新打包之前創(chuàng)建的原始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. 接下來應該讀什么

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

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

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

Part III. 使用 Spring Boot

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

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

13. 構建系統(tǒng)

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

13.1 依賴管理

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

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

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

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

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 所述的屬性來覆蓋單個依賴關系。 要實現(xiàn)相同的結果,您需要在spring-boot-dependencies條目之前在項目的dependencyManagement中添加一個條目。 例如,要升級到另一個Spring Data發(fā)行版本,您需要將以下內容添加到您的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插件,可以將項目打包成可執(zhí)行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也是可用的,它提供了從源代碼創(chuàng)建可執(zhí)行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創(chuàng)建可執(zhí)行文件。

要聲明依賴關系,典型的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節(jié)“從Ant構建可執(zhí)行存檔,而不使用spring-boot-antlib”如果不想使用spring-boot-antlib模塊,請參閱“操作方法”。

13.5 啟動器

啟動器是一組方便的依賴關系描述符,可以包含在應用程序中。 您可以獲得所需的所有Spring和相關技術的一站式服務,無需通過示例代碼搜索和復制粘貼依賴配置。 例如,如果要開始使用Spring和JPA進行數(shù)據(jù)庫訪問,那么只需在項目中包含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”來獲取完整的列表。 如創(chuàng)建自己的啟動器部分所述,第三方啟動程序不應該從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面向文檔的數(shù)據(jù)庫和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的電子郵件發(fā)送支持的啟動器Pom
spring-boot-starter-data-redisRedis key-value 數(shù)據(jù)存儲與Spring Data Redis和Jedis客戶端啟動器Pom
spring-boot-starter-web使用Spring MVC構建Web,包括RESTful應用程序。使用Tomcat作為默認的嵌入式容器的啟動器Pom
spring-boot-starter-data-gemfire使用GemFire分布式數(shù)據(jù)存儲和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圖數(shù)據(jù)庫和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分布式數(shù)據(jù)庫和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數(shù)據(jù)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面向文檔的數(shù)據(jù)庫和Spring Data MongoDB的啟動器Pom
spring-boot-starter-jooq使用jOOQ訪問SQL數(shù)據(jù)庫的啟動器。 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數(shù)據(jù)庫的啟動器Pom

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

表13.2 Spring Boot生產環(huán)境啟動器

名稱描述Pom
spring-boot-starter-actuator使用Spring Boot Actuator提供生產準備功能,可幫助您監(jiān)控和管理應用程序的啟動器Pom
spring-boot-starter-remote-shell使用CRaSH遠程shell通過SSH監(jiān)視和管理您的應用程序的啟動器。 自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

有關社區(qū)貢獻的更多啟動器的列表,請參閱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示例已經在網上發(fā)布。 如果可能的話我們建議始終嘗試使用等效的基于Java的配置。 搜索 enable* 注解可以是一個很好的起點。

15.1 導入其他配置類

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

15.2 導入XML配置

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

16. 自動配置

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

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

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

16.1逐漸取代自動配置

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

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

16.2 禁用指定的自動配置

如果您發(fā)現(xiàn)正在使用一些不需要的自動配置類,可以使用@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及其依賴注入關系。 為了簡單起見,我們發(fā)現(xiàn)使用@ComponentScan搜索bean,結合@Autowired構造函數(shù)(constructor)注入效果很好。

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

以下是一個@Service Bean的例子,我們可以使用構造函數(shù)注入獲取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 只有一個構造函數(shù),則可以省略@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>

}

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

18. 使用@SpringBootApplication注解

許多Spring Boot開發(fā)人員總是使用@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服務器的最大優(yōu)點之一就是可以按照你想用其他任何方式運行應用程序。調試Spring Boot應用程序也很容易; 您不需要任何專門的IDE插件或擴展。

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

19.1 從IDE運行

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

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

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

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

如果您使用Spring Boot 的 Maven或Gradle插件創(chuàng)建可執(zhí)行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

您可能還需要使用一些有用的操作系統(tǒng)環(huán)境變量:

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

19.4 使用Gradle插件

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

$ gradle bootRun

您可能還想使用這個有用的操作系統(tǒng)環(huán)境變量:

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

19.5 熱插拔

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

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

20. 開發(fā)工具

Spring Boot包括一組額外的工具,可以使應用程序開發(fā)體驗更加愉快。 spring-boot-devtools模塊可以包含在任何項目中,以提供額外的開發(fā)時功能。 要包含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") }

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

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

20.1 屬性默認值

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

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

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

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

20.2 自動重啟

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

觸發(fā)重啟

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

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

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

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

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

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

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

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

20.2.1 排除資源

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

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

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

20.2.2 監(jiān)視額外的路徑

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

20.2.3 禁用重啟

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

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

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

20.2.4 使用觸發(fā)文件

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

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

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

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

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

默認情況下,IDE中的任何打開的項目將使用“重新啟動”類加載器加載,任何常規(guī).jar文件將使用“base”類加載器加載。 如果您在多模塊項目上工作,而不是每個模塊都導入到IDE中,則可能需要自定義事件。 為此,您可以創(chuàng)建一個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反序列化的對象無效。 如果需要反序列化數(shù)據(jù),可能需要使用Spring的ConfigurableObjectInputStream與Thread.currentThread()。getContextClassLoader()組合使用。

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

20.3 LiveReload

spring-boot-devtools模塊包括一個嵌入式LiveReload服務器,可以在資源更改時用于觸發(fā)瀏覽器刷新。 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應用程序。 例如,要配置重新啟動以始終使用觸發(fā)器文件,您可以添加以下內容:

~/.spring-boot-devtools.properties.

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

20.5遠程應用

Spring Boot開發(fā)工具不僅限于本地開發(fā)。 遠程運行應用程序時也可以使用多種功能。 遠程支持是可選擇的,要使其能夠確保重新打包的存檔中包含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。 傳遞給應用程序的必選參數(shù)應該是您要連接到的遠程URL。

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

  • 從Run 菜單中選擇Run Configurations…。
  • 創(chuàng)建一個新的Java Application “l(fā)aunch configuration”。
  • 瀏覽my-app項目。
  • 使用org.springframework.boot.devtools.RemoteSpringApplication作為主類。
  • 將https://myapp.cfapps.io添加到程序參數(shù)(或任何遠程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//作為連接協(xié)議,以便流量被加密,防止密碼被攔截。

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

20.5.2 遠程更新

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

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

20.5.3 遠程調試隧道

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

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

您需要確保遠程應用程序啟用遠程調試啟用。 通常可以通過配置JAVA_OPTS來實現(xiàn)。 例如,使用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)更改為更合適的值(大多數(shù)情況下,60000可以正常工作)。

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

21. 包裝您的應用程序到生產環(huán)境

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

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

22. 接下來應該讀什么

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

Part IV. Spring Boot 功能

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

23. SpringApplication

SpringApplication類提供了一種方便的方法來引導將從main()方法啟動的Spring應用程序。 在許多情況下,您只需委派靜態(tài)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消息,包括用戶啟動應用程序一些相關的啟動細節(jié)。

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實現(xiàn),您可以非常容易地添加自己的實現(xiàn)。

如果沒有故障分析器(analyzers)能夠處理異常,您仍然可以顯示完整的自動配置報告,以更好地了解出現(xiàn)的問題。 為此,您需要啟用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藝術表現(xiàn),并打印在任何文字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 如接口,并實現(xiàn)自己的printBanner() 方法。

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

23.3 定制SpringApplication

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

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

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

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

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

23.4 流式構建 API

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

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

例如:

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

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

23.5 Application events and listeners

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

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

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

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

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

    23.6 Web 環(huán)境

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

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

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

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

    23.7 訪問應用程序參數(shù)

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

    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注解注入應用程序參數(shù)。

    23.8 使用ApplicationRunner或CommandLineRunner

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

    CommandLineRunner接口提供對應用程序參數(shù)的訪問(簡單的字符串數(shù)組),而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必須按特定順序調用,您可以實現(xiàn)org.springframework.core.Ordered接口,也可以使用org.springframework.core.annotation.Order注解。

    23.9 Application exit

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

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

    23.10 管理功能

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

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

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

    24. 外部配置

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

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

  • 在您的HOME目錄設置的Devtools全局屬性(~/.spring-boot-devtools.properties)。
  • 單元測試中的 @TestPropertySource 注解。
  • 單元測試中的 @SpringBootTest#properties 注解屬性
  • 命令行參數(shù)。
  • SPRING_APPLICATION_JSON 中的屬性值(內嵌JSON嵌入到環(huán)境變量或系統(tǒng)屬性中)。
  • ServletConfig 初始化參數(shù)。
  • ServletContext 初始化參數(shù)。
  • 來自 java:comp/env 的JNDI屬性。
  • Java系統(tǒng)屬性(System.getProperties())。
  • 操作系統(tǒng)環(huán)境變量。
  • 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設置)。
  • 一個具體的例子,假設你開發(fā)一個使用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 屬性提供了默認屬性值。 在新環(huán)境中運行時,可以在您的jar外部提供一個application.properties來覆蓋 name 屬性; 對于一次性測試,您可以使用特定的命令行開關啟動(例如,java -jar app.jar --name="Spring")。

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

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

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

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

    或命令行參數(shù):

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

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

    24.1 配置隨機值

    RandomValuePropertySource可用于注入隨機值(例如,進入秘密或測試用例)。 它可以產生整數(shù),長整數(shù),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是整數(shù)。 如果提供max,則值為最小值,max為最大值(獨占)。

    24.2 訪問命令行屬性

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

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

    24.3 應用程序屬性文件

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

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

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

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

    $ 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一開始就被用于確定哪些文件必須被加載,因此必須將它們定義為環(huán)境屬性(通常是OS env,system屬性或命令行參數(shù))。

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

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

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

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

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

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

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

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

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

    24.5 properties 文件中的占位符

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

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

    您也可以使用此技術創(chuàng)建現(xiàn)有Spring Boot屬性的“簡寫“。 有關詳細信息,請參見第72.4節(jié)“使用”短命令行參數(shù)“how-to”。

    24.6 使用YAML替代 Properties

    YAML是JSON的超集,因此這是分層配置數(shù)據(jù)一種非常方便的格式,。 每當您的類路徑中都有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環(huán)境中的屬性文件

    可以使用YamlPropertySourceLoader類在Spring環(huán)境中將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

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

    如果應用程序上下文啟動時沒有顯式激活,默認配置文件將被激活。 所以在這個YAML中,我們?yōu)閟ecurity.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實例添加到列表中,并且不會將項目合并。

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

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

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

    24.7 類型安全的配置屬性

    使用@Value(“${property}”)注釋來注入配置屬性有時可能很麻煩,特別是如果您正在使用多個層次結構的屬性或數(shù)據(jù)時。 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修改。
    • 集合和數(shù)組可以通過索引(通常使用YAML)或使用單個逗號分隔值(Properties中)來訪問。 在后一種情況下,setter方法是強制性的。 我們建議總是為這樣的類型添加一個設置器。 如果您初始化集合,請確保它不是不可變的(如上例所示)
    • 如果已初始化嵌套POJO屬性(如上例中的Security字段),則不需要setter方法。如果您希望binder使用其默認構造函數(shù)即時創(chuàng)建實例,則需要一個setter。

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

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

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

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

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

    即使上述配置將為FooProperties創(chuàng)建一個常規(guī)bean,我們建議@ConfigurationProperties僅處理環(huán)境,特別是不從上下文中注入其他bean。 話雖如此,@EnableConfigurationProperties注釋也會自動應用于您的項目,以便使用@ConfigurationProperties注釋的任何現(xiàn)有的bean都將從環(huán)境配置。 您可以通過確保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可以為自己的密鑰提供自動完成的元數(shù)據(jù)文件,有關詳細信息,請參見附錄B,配置元數(shù)據(jù)附錄。

    24.7.1第三方配置

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

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

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

    24.7.2 寬松的綁定

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

    例如,給定以下@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大寫格式 推薦使用系統(tǒng)環(huán)境變量時。

    24.7.3屬性轉換

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

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

    24.7.4 @ConfigurationProperties驗證

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

    @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>

    }

    為了驗證嵌套屬性的值,您必須將關聯(lián)字段注釋為@Valid以觸發(fā)其驗證。 例如,基于上述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>}

    }

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

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

    24.7.5 @ConfigurationProperties 對比 @Value

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

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

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

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

    25. 配置文件(Profiles)

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

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

    }

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

    spring.profiles.active=dev,hsqldb

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

    25.1添加激活配置文件

    spring.profiles.active屬性遵循與其他屬性相同的優(yōu)先級規(guī)則,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節(jié)“根據(jù)環(huán)境更改配置”。

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

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

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

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

    26. 日志

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

    默認情況下,如果使用'Starters',將會使用Logback。 還包括適當?shù)腖ogback路由,以確保使用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。
    • ---分隔符來區(qū)分實際日志消息的開始。
    • 線程名稱 - 括在方括號中(可能會截斷控制臺輸出)。
    • 記錄器名稱 - 這通常是源類名(通常縮寫)。
    • 日志消息。

    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關鍵字配置顏色編碼。 在最簡單的形式下,轉換器將根據(jù)日志級別對輸出進行著色,例如:

    %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級別的消息。

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

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

    26.4 日志級別

    所有支持的日志記錄系統(tǒng)都可以在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 自定義日志配置

    可以通過在類路徑中包含適當?shù)膸靵砑せ罡鞣N日志系統(tǒng),并通過在類路徑的根目錄中提供合適的配置文件,或在Spring Environment屬性logging.config指定的位置進一步配置。

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

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

    根據(jù)您的日志記錄系統(tǒng),將會加載以下文件:

    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存在已知的類加載問題,從“可執(zhí)行jar”運行時會導致問題。 我們建議您盡可能避免。

    幫助定制一些其他屬性從Spring環(huán)境轉移到系統(tǒng)屬性:

    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用于呈現(xiàn)日志級別的格式(默認%5p)。 (僅支持默認logback設置。)
    PIDPID當前進程ID(如果可能的話,當未被定義為OS環(huán)境變量時被發(fā)現(xiàn))。

    支持的所有日志記錄系統(tǒng)在分析其配置文件時可以查看系統(tǒng)屬性。 有關示例,請參閱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>標簽允許您根據(jù)活動的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 環(huán)境屬性

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

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

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

    27.1 “Spring Web MVC框架”

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

    以下是@RestController用于提供JSON數(shù)據(jù)的典型示例:

    @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提供了適用于大多數(shù)應用程序的Spring MVC的自動配置。

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

    • 包含ContentNegotiatingViewResolver和BeanNameViewResolver bean。
    • 支持提供靜態(tài)資源,包括對WebJars的支持(見下文)。
    • Converter,GenericConverter,Formatter beans的自動注冊。
    • 支持HttpMessageConverters(見下文)。
    • 自動注冊MessageCodesResolver(見下文)。
    • 靜態(tài)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數(shù)據(jù),則可能需要編寫自己的JsonSerializer和JsonDeserializer類。 自定義序列化程序通常通過一個模塊注冊到Jackson,但是Spring Boot提供了一個備用的@JsonComponent注釋,可以更容易地直接注冊Spring Bean。

    您可以直接在JsonSerializer或JsonDeserializer實現(xiàn)中使用@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進行元注解的,所以常規(guī)的組件掃描規(guī)則適用。

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

    27.1.4 MessageCodesResolver

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

    27.1.5 靜態(tài)內容

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

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

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

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

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

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

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

    Spring Boot還支持Spring MVC提供的高級資源處理功能,允許使用例如緩存靜態(tài)資源或使用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。

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

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

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

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

    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在配置的靜態(tài)內容位置和類路徑的根目錄(按順序)中查找favicon.ico。 如果文件存在,它將被自動用作應用程序的圖標。

    27.1.7 ConfigurableWebBindingInitializer

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

    27.1.8 模板引擎

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

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

    • FreeMarker
    • Groovy
    • Thymeleaf
    • Mustache

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

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

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

    27.1.9 錯誤處理

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

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

    自定義錯誤頁面

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

    例如,要將404映射到靜態(tài)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>

    對于更復雜的映射,您還可以添加實現(xiàn)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> ... }

    }

    您還可以使用常規(guī)的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會使用其錯誤頁面過濾器將具有錯誤狀態(tài)的請求轉發(fā)到相應的錯誤頁面。 如果響應尚未提交,則該請求只能轉發(fā)到正確的錯誤頁面。 默認情況下,WebSphere Application Server 8.0及更高版本在成功完成servlet的服務方法后提交響應。 您應該通過將com.ibm.ws.webcontainer.invokeFlushAfterService設置為false來禁用此行為

    27.1.10 Spring HATEOAS

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

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

    27.1.11 CORS 支持

    跨原始資源共享(CORS)是大多數(shù)瀏覽器實現(xiàn)的W3C規(guī)范,允許您以靈活的方式指定什么樣的跨域請求被授權,而不是使用一些不太安全和不太強大的方法,如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 ,您可以使用一個可用的實現(xiàn)而不是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對掃描可執(zhí)行檔案的包是相當有限的。 例如,當運行可執(zhí)行的war文件時,它無法掃描在WEB-INF/classes中找到的包中的端點(endpoints)。 為了避免這種限制,不應使packages方法,并且應使用上述寄存器方法單獨注冊(register)端點。

    您還可以注冊任意數(shù)量的ResourceConfigCustomizer的實現(xiàn)bean,以實現(xiàn)更高級的自定義。

    所有注冊的端點都應為具有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進行自定義。您可以通過創(chuàng)建一個自己的同名文件來禁用或覆蓋該bean。 您也可以通過設置spring.jersey.type = filter(在這種情況下,@Bean來替換或替換為jerseyFilterRegistration),使用Filter而不是Servlet。 servlet有一個@Order,您可以使用spring.jersey.filter.order設置。 可以使用spring.jersey.init.* 給出Servlet和過濾器注冊的init參數(shù),以指定屬性的映射。

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

    27.3 嵌入式servlet容器支持

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

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

    27.3.1 Servlets, Filters 和 listeners

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

    將Servlets,過濾器和監(jiān)聽器注冊為Spring bean

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

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

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

    27.3.2 Servlet Context 初始化

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

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

    掃描Servlet,過濾器和監(jiān)聽器

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

    @ServletComponentScan在獨立容器中不起作用,在該容器中將使用容器的內置發(fā)現(xiàn)機制。

    27.3.3 EmbeddedWebApplicationContext

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

    您通常不需要知道這些實現(xiàn)類。 大多數(shù)應用程序將被自動配置,并將代表您創(chuàng)建適當?shù)腁pplicationContext和EmbeddedServletContainerFactory。

    27.3.4 定制嵌入式servlet容器

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

    常用服務器設置包括:

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

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

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

    用程序定制

    如果需要以編程方式配置嵌入式servlet容器,您可以注冊一個實現(xiàn)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容器(并打包為可執(zhí)行文檔)的Spring Boot應用程序時,對JSP支持有一些限制。

    • 可以使用Tomcat和war包,即可執(zhí)行的war將會起作用,并且也可以部署到標準容器(不限于但包括Tomcat)中。 由于Tomcat中的硬編碼文件模式,可執(zhí)行的jar將無法正常工作。
    • 可以使用Jetty和war包,即可執(zhí)行的war將會起作用,并且也可以部署到任何標準的容器,它應該可以工作。
    • Undertow不支持JSP。
    • 創(chuàng)建自定義的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和從那里導入的類中實現(xiàn)(用于Web安全的SpringBootWebSecurityConfiguration和用于認證配置的AuthenticationManagerConfiguration,這在非Web應用程序中也是相關的)。 要完全關閉默認的Web應用程序安全配置,您可以使用@EnableWebSecurity添加一個bean(這不會禁用身份驗證管理器配置或Actuator的安全性)。 要定制它,您通常使用WebSecurityConfigurerAdapter類型的外部屬性和bean(例如添加基于表單的登錄)。 要關閉身份驗證管理器配置,您可以添加AuthenticationManager類型的bean,或者通過將AuthenticationManagerBuilder自動連接到您的一個@Configuration類中的方法來配置全局AuthenticationManager。 Spring Boot示例中有幾個安全應用程序可以讓您開始使用常見的用例。

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

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

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

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

    28.1 OAuth2

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

    28.1.1 授權服務器

    要創(chuàng)建授權服務器并授予訪問令牌,您需要使用@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。 用戶憑據(jù)是普通的Spring Security用戶details (在Spring引導中默認為“user”和隨機密碼)。

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

    28.1.2 資源服務器

    要使用訪問令牌(token),您需要一個資源服務器(可以與授權服務器相同)。 創(chuàng)建資源服務器很簡單,只需添加@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,那么您可以設置一個標志,表示優(yōu)先于另一個(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的過濾器鏈保護,默認情況下保護執(zhí)行器(actuator)端點的過濾器(所以執(zhí)行器(actuator)端點將保留在HTTP Basic上,除非更改順序)。

    28.2 User Info中的令牌類型

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

    28.3 自定義用戶信息RestTemplate

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

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

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

    28.3.1 Client

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

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

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

    此配置使用security.oauth2.client.*作為憑據(jù)(可能與授權服務器中使用的相同),但另外還需要知道授權服務器中的授權和令牌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或其他提供商注冊自己的客戶端應用程序以獲得更大的靈活性),這些特定的憑據(jù)才會起作用。

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

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

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

    28.3.2 單點登錄

    OAuth2客戶端可用于從提供商獲取用戶詳細信息(如果此類功能可用),然后將其轉換為Spring Security的身份驗證令牌。 以上資源服務器通過user-info-uri屬性支持此功能這是基于OAuth2的單點登錄(SSO)協(xié)議的基礎,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指定的路徑) 。

    要自定義保護的訪問規(guī)則或路徑,因此您可以添加“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也在使用中,您會發(fā)現(xiàn):

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

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

    29. 使用SQL數(shù)據(jù)庫

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

    29.1 配置DataSource

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

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

    29.1.1 嵌入式數(shù)據(jù)庫支持

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

    “How-to”部分包含如何初始化數(shù)據(jù)庫

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

    如果您在測試中使用此功能,您可能會注意到,整個測試套件都會重復使用相同的數(shù)據(jù)庫,而不管您使用的應用程序上下文的數(shù)量。 如果要確保每個上下文都有一個單獨的嵌入式數(shù)據(jù)庫,您應該將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>

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

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

    29.1.2 連接到生產環(huán)境數(shù)據(jù)庫

    生產數(shù)據(jù)庫連接也可以使用連接池數(shù)據(jù)源自動配置。 這是選擇具體實現(xiàn)的算法:

    • 我們更喜歡Tomcat連接池DataSource的性能和并發(fā)性,所以如果可用,我們總是選擇它。
    • 否則,如果HikariCP可用,我們將使用它。
    • 如果Tomcat池數(shù)據(jù)源和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,則不會發(fā)生自動配置。

    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將嘗試自動配置嵌入式數(shù)據(jù)庫。

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

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

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

    例如,如果您正在使用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是一種標準技術,可讓您將對象映射到關系數(shù)據(jù)庫。 spring-boot-starter-data-jpa POM提供了一種快速入門的方法。 它提供以下關鍵依賴:

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

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

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

    29.3.1 實體類

    傳統(tǒng)上,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節(jié)“從Spring配置中分離@Entity定義”操作方法。

    29.3.2 Spring Data JPA Repositories

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

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

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

    這是一個典型的Spring數(shù)據(jù)庫:

    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 創(chuàng)建和刪除JPA數(shù)據(jù)庫

    默認情況下,僅當您使用嵌入式數(shù)據(jù)庫(H2,HSQL或Derby)時才會自動創(chuàng)建JPA數(shù)據(jù)庫。 您可以使用spring.jpa。*屬性顯式配置JPA設置。 例如,要創(chuàng)建和刪除表,您可以將以下內容添加到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執(zhí)行(或驗證)將延遲到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數(shù)據(jù)庫提供了一個基于瀏覽器的控制臺,Spring Boot可以為您自動配置。 滿足以下條件時,控制臺將自動配置:

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

    如果您不使用Spring Boot的開發(fā)人員工具,但仍希望使用H2的控制臺,那么可以通過配置一個值為true的spring.h2.console.enabled屬性來實現(xiàn)。 H2控制臺僅用于開發(fā)期間,因此應注意確保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的產品,它從數(shù)據(jù)庫生成Java代碼,并通過流暢的API構建類型安全的SQL查詢。 商業(yè)版和開源版都可以與Spring Boot一起使用。

    29.5.1 代碼生成

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

    <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定義可以實現(xiàn)更高級的定制,這些定義將在創(chuàng)建jOOQ配置時使用。您可以為以下jOOQ類型定義bean:

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

    如果要完全控制jOOQ配置,您還可以創(chuàng)建自己的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是一個緩存,消息代理并有功能豐富的鍵值存儲數(shù)據(jù)庫。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文檔數(shù)據(jù)庫,它使用類似JSON的架構,而不是傳統(tǒng)的基于表的關系數(shù)據(jù)。 Spring Boot為MongoDB提供了幾種便利,包括spring-boot-starter-data-mongodb'Starter'。

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

    總結

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

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