第4章 使用 Spring Boot

使用 Spring Boot

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

若是您剛剛開始使用Spring Boot,那麼在深刻本部分以前,您應該閱讀入門指南java

13. 構建系統

強烈建議您選擇一個支持依賴管理並可使用「Maven Central」存儲庫的構建系統。 咱們建議您選擇Maven或Gradle。 Spring Boot 能夠與其餘構建系統(例如 Ant )配合使用,可是它們不會獲得很好的支持。git

13.1 依賴管理

每一個版本的Spring Boot提供了一個它所支持的依賴關係列表。 實際上,您不須要爲構建配置文件中的這些依賴關係提供版本,由於Spring Boot會爲您進行管理這些依賴的版本。 當您升級Spring Boot自己時,這些依賴關係也將以一致的進行升級。github

若是您以爲有必要,您仍然能夠指定一個版本並覆蓋Spring Boot建議的版本。web

管理的列表中包含可使用Spring Boot的全部Spring模塊以及第三方庫的精簡列表。 該列表可做爲標準的物料(Materials)清單(spring-boot-dependencies)使用,而且還提供了對 MavenGradle 的額外支持。正則表達式

Spring Boot的每一個版本與Spring Framework的基本版本相關聯,所以咱們強烈建議您不要本身指定其版本。redis

13.2 Maven

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

  • Java 1.6做爲默認編譯器級別。
  • 源代碼UTF-8編碼。
  • 依賴關係管理,容許您省略常見依賴的標籤,其默認版本繼承自spring-boot-dependencies POM。
  • 更合理的資源過濾
  • 更合理的插件配置(exec pluginsurefireGit commit IDshade)。
  • 針對application.properties和application.yml的更合理的資源過濾,包括特定的文件(例如application-foo.properties和application-foo.yml)
  • 最後一點:因爲默認的配置文件接受Spring樣式佔位符(${…}),Maven過濾更改成使用 @..@ 佔位符(您可使用Maven屬性resource.delimiter覆蓋它)。

13.2.1 繼承啓動器parent

要將項目配置爲繼承spring-boot-starter-parent,只需設置標籤以下:mongodb

<!-- 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版本號。 若是您導入其餘起始器,則能夠放心地省略他們的版本號。shell

經過該設置,您還能夠經過覆蓋本身的項目中的屬性來覆蓋單個依賴。 例如,要升級到另外一個 Spring Data 版本序列,您須要將如下內容添加到您的pom.xml中。

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

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

13.2.2 使用沒有父POM的 Spring Boot

不是每一個人都喜歡從spring-boot-starter-parent POM繼承。 您公司可能有本身標準的父母,或者您可能只但願明確聲明全部的Maven配置。

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

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

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

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

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

13.2.3 更改Java版本

spring-boot-starter-parent選擇至關保守的Java兼容性版本。 若是要遵循咱們的建議並使用更高版本的Java版本,能夠添加java.version屬性:

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

13.2.4 使用Spring Boot Maven插件

Spring Boot包括一個Maven插件,能夠將項目打包成可執行jar。 若是要使用它,請將插件添加到部分:

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

若是您使用Spring Boot啓動器 parent pom,則只須要添加這個插件,除非您要更改parent中定義的設置,不然不須要進行配置。

13.3 Gradle

Gradle用戶能夠直接在其依賴關係部分導入「啓動器」。 不像Maven,沒有「超級父」導入來共享一些配置。

repositories {
jcenter()
}

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

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

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


repositories {
jcenter()
}

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

13.4 Ant

可使用Apache Ant + Ivy構建Spring Boot項目。 spring-boot-antlib「AntLib」模塊也可用於幫助Ant建立可執行文件。

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

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

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

<project
xmlns:ivy="antlib:org.apache.ivy.ant"
xmlns:spring-boot="antlib:org.springframework.boot.ant"
name="myapp" default="build">

<property name="spring-boot.version" value="1.3.0.BUILD-SNAPSHOT" />

<target name="resolve" description="--> retrieve dependencies with ivy">
<ivy:retrieve pattern="lib/[conf]/[artifact]-[type]-[revision].[ext]" />
</target>

<target name="classpaths" depends="resolve">
<path id="compile.classpath">
<fileset dir="lib/compile" includes="*.jar" />
</path>
</target>

<target name="init" depends="classpaths">
<mkdir dir="build/classes" />
</target>

<target name="compile" depends="init" description="compile">
<javac srcdir="src/main/java" destdir="build/classes" classpathref="compile.classpath" />
</target>

<target name="build" depends="compile">
<spring-boot:exejar destfile="build/myapp.jar" classes="build/classes">
<spring-boot:lib>
<fileset dir="lib/runtime" />
</spring-boot:lib>
</spring-boot:exejar>
</target>
</project>

請參見第84.10節「從Ant構建可執行存檔,而不使用spring-boot-antlib」若是不想使用spring-boot-antlib模塊,請參閱「操做方法」。

13.5 啓動器

啓動器是一組方便的依賴關係描述符,能夠包含在應用程序中。 您能夠得到所需的全部Spring和相關技術的一站式服務,無需經過示例代碼搜索和複製粘貼依賴配置。 例如,若是要開始使用Spring和JPA進行數據庫訪問,那麼只需在項目中包含spring-boot-starter-data-jpa依賴關係便可。

啓動器包含許多依賴關係,包括您須要使項目快速啓動並運行,並具備一致的受支持的依賴傳遞關係。

What’s in a name

全部正式起動器都遵循相似的命名模式: spring-boot-starter- ,其中 是特定類型的應用程序。 這個命名結構旨在幫助你快速找到一個啓動器。 許多IDE中的Maven插件容許您按名稱搜索依賴項。 例如,安裝Eclipse或STS的Maven插件後,您能夠簡單地在POM編輯器中點擊 Dependency Hierarchy,並在filter輸入「spring-boot-starter」來獲取完整的列表。
建立本身的啓動器部分所述,第三方啓動程序不該該從Spring-boot開始,由於它是爲正式的Spring Boot artifacts 保留的。 acme 的 第三方啓動器一般被命名爲acme-spring-boot-starter。

Spring Boot在org.springframework.boot組下提供瞭如下應用程序啓動器:

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

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

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

表13.2 Spring Boot生產環境啓動器

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

最後,Spring Boot還包括一些啓動器,若是要排除或替換特定的技術,可使用它們:

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

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

14. 構建代碼

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

14.1 不要使用「default」包

當類不包括包聲明時,它被認爲是在「默認包」中。 一般不鼓勵使用「默認包」,並應該避免使用。 對於使用@ComponentScan,@EntityScan或@SpringBootApplication註解的Spring Boot應用程序,可能會有一些特殊的問題,由於每一個jar的每一個類都將被讀取。

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

14.2 查找主應用程序類

咱們一般建議您將應用程序主類放到其餘類之上的根包(root package)中。 @EnableAutoConfiguration註解一般放置在您的主類上,它隱式定義了某些項目的基本「搜索包」。 例如,若是您正在編寫JPA應用程序,則@EnableAutoConfiguration註解類的包將用於搜索@Entity項。

使用根包(root package)還可使用@ComponentScan註釋,而不須要指定basePackage屬性。 若是您的主類在根包中,也可使用@SpringBootApplication註釋。

這是一個典型的佈局:

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

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

package com.example.myproject;

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

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {

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

}

15. 配置類

Spring Boot支持基於Java的配置。雖然可使用XML配置用SpringApplication.run(),但咱們一般建議您的主source是@Configuration類。 一般,定義main方法的類也是做爲主要的@Configuration一個很好的選擇。

許多使用XML配置的Spring示例已經在網上發佈。 若是可能的話咱們建議始終嘗試使用等效的基於Java的配置。 搜索 enable* 註解能夠是一個很好的起點。

15.1 導入其餘配置類

您不須要將全部的@Configuration放在一個類中。 @Import註解可用於導入其餘配置類。 或者,您可使用@ComponentScan自動掃描全部Spring組件,包括@Configuration類。

15.2 導入XML配置

若是您必須使用基於XML的配置,咱們建議您仍然從@Configuration類開始。 而後,您可使用的@ImportResource註釋來加載XML配置文件。

16. 自動配置

Spring Boot 會根據您添加的jar依賴關係自動配置您的Spring應用程序。例如,若是HSQLDB在您的類路徑上,而且您沒有手動配置任何數據庫鏈接bean,那麼咱們將自動配置內存數據庫。

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

您應該只添加一個@EnableAutoConfiguration註解。 咱們一般建議您將其添加到主@Configuration類中。

16.1逐漸取代自動配置

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

若是您須要瞭解當前有哪些自動配置,以及爲何,請使用–debug開關啓動應用程序。 這將啓用debug日誌,並將自動配置日誌記錄到控制檯。

16.2 禁用指定的自動配置

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

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

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

若是類不在classpath路徑上,則可使用註釋的excludeName屬性,並指定全限定名(fully qualified name)。 最後,您還能夠經過spring.autoconfigure.exclude屬性控制要排除的自動配置類列表。

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

17. Spring Beans 和 依賴注入

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

若是您按照上述建議(將應用程序類放在根包(root package)中)構建代碼,則可使用
@ComponentScan而不使用任何參數。 全部應用程序組件(@Component,@Service,@Repository,@Controller等)將自動註冊爲Spring Bean。

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

package com.example.service;

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

@Service
public class DatabaseAccountService implements AccountService {

private final RiskAssessor riskAssessor;

@Autowired
public DatabaseAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}

// ...

}

若是一個bean 只有一個構造函數,則能夠省略@Autowired。

@Service
public class DatabaseAccountService implements AccountService {

private final RiskAssessor riskAssessor;

public DatabaseAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}

// ...

}

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

18. 使用@SpringBootApplication註解

許多Spring Boot開發人員老是使用@Configuration,@EnableAutoConfiguration和@ComponentScan來標註它們的主類。 因爲這些註解常常一塊兒使用(特別是若是您遵循以前說的最佳實踐),Spring Boot提供了一個方便的@SpringBootApplication註解做爲這三個的替代方法。

@SpringBootApplication註解至關於使用@Configuration,@EnableAutoConfiguration和@ComponentScan和他們的默認屬性:

package com.example.myproject;

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

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

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

}

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

19. 運行你的應用程序

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

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

19.1 從IDE運行

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

若是您沒法將項目直接導入到IDE中,則可使用構建插件生成IDE元數據。 Maven包括Eclipse和IDEA的插件; Gradle爲各類IDE提供插件。

若是您不當心運行了兩次Web應用程序,您將看到「Port already in use」中的錯誤。 使用STS用戶可使用從新啓動按鈕而不是運行以確保任何現有實例已關閉。

19.2 做爲已打包應用程序運行

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

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

也能夠啓用遠程調試支持運行打包的應用程序。 這容許您將調試器添加到打包的應用程序中:

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

19.3 使用 Maven 插件

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

$ mvn spring-boot:run

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

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

19.4 使用Gradle插件

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

$ gradle bootRun

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

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

19.5 熱插拔

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

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

20. 開發工具

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

Maven:

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

Gradle:

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

當運行徹底打包的應用程序時,開發人員工具將自動禁用。 若是您的應用程序是使用java -jar啓動的,或者是使用特殊的類加載器啓動,那麼它將會被認爲是「生產環境的應用程序」。 將開發工具依賴關係標記爲可選(optional)是一種最佳作法,能夠防止使用項目將devtools傳遞性地應用於其餘模塊。 Gradle不支持開箱即用的可選依賴項,所以您可能但願在此期間查看propdeps-plugin

從新打包的jar包默認狀況下不包含devtools。 若是要使用某些遠程devtools功能,您須要禁用excludeDevtools 構建下的屬性以包含devtools。 該屬性支持Maven和Gradle插件。

20.1 屬性默認值

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

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

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

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

20.2 自動重啓

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

觸發重啓

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

只要 forking 被啓用,您也能夠經過支持的構建插件(即Maven和Gradle)啓動應用程序,由於DevTools須要一個單獨的應用程序類加載器才能正常運行。Gradle和Maven默認狀況下在類路徑上檢DevTools。

自動重啓當與LiveReload一塊兒使用時工做很是好。 詳見下文。 若是您使用JRebel,自動重啓將被禁用,有利於動態類從新加載。 其餘devtools功能仍然可使用(如LiveReload和屬性覆蓋)。

DevTools依賴於應用程序上下文的關閉鉤子,以在從新啓動期間關閉它。 若是禁用了關閉掛鉤(SpringApplication.setRegisterShutdownHook(false)),DevTools將沒法正常工做。

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

從新啓動(Restart) vs 從新加載(Reload)

Spring Boot提供的從新啓動技術使用兩個類加載器。 不會改的類(例如,來自第三方的jar)被加載到基類加載器中。 您正在開發的類被加載到從新啓動(restart)類加載器中。 當應用程序從新啓動時,從新啓動類加載器將被丟棄,並建立一個新的類加載器。 這種方法意味着應用程序從新啓動一般比「冷啓動」快得多,由於基類加載器已經可使用。

若是發現從新啓動對應用程序不夠快,或遇到類加載問題,您能夠考慮來自ZeroTurnaround的JRebel等從新加載技術。 這些工做經過在加載類時重寫(rewriting)類,使其更適合從新加載。 Spring Loaded提供了另外一個選項,可是它在不少框架上不支持,而且不支持商用。

20.2.1 排除資源

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

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

若是要保留這些默認值並添加其餘排除項,請改用spring.devtools.restart.additional-exclude屬性。

20.2.2 監視額外的路徑

有時當您對不在類路徑中的文件進行更改時,須要從新啓動或從新加載應用程序。爲此,請使用spring.devtools.restart.additional-paths屬性來配置其餘路徑以監視更改。 您可使用上述的spring.devtools.restart.exclude屬性來控制附加路徑下的更改是否會觸發徹底從新啓動或只是實時從新加載

20.2.3 禁用重啓

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

例如,若是您須要徹底禁用從新啓動支持,由於它在一些特定庫中不能正常運行,則須要在調用SpringApplication.run(…)以前設置System屬性。 例如:

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

20.2.4 使用觸發文件

若是您使用IDE工具編寫代碼,更改文件,則您可能但願僅在特定時間觸發從新啓動。 爲此,您可使用「觸發文件」,這是一個特殊文件,當您要實際觸發從新啓動檢查時,必須修改它。 更改文件只會觸發檢查,只有在Devtools檢測到它必須執行某些操做時纔會從新啓動。 觸發文件能夠手動更新,也能夠經過IDE插件更新。

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

您可能但願將spring.devtools.restart.trigger-file設置爲全局設置,以使全部項目的行爲方式相同。

20.2.5 自定義從新啓動類加載器

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

默認狀況下,IDE中的任何打開的項目將使用「從新啓動」類加載器加載,任何常規.jar文件將使用「base」類加載器加載。 若是您在多模塊項目上工做,而不是每一個模塊都導入到IDE中,則可能須要自定義事件。 爲此,您能夠建立一個META-INF / spring-devtools.properties文件。

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

例如:

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

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

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

20.2.6 已知的限制

從新啓動功能對於使用標準ObjectInputStream反序列化的對象無效。 若是須要反序列化數據,可能須要使用Spring的ConfigurableObjectInputStream與Thread.currentThread()。getContextClassLoader()組合使用。

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

20.3 LiveReload

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

若是您不想在應用程序運行時啓動LiveReload服務器,則能夠將spring.devtools.livereload.enabled屬性設置爲false。

一次只能運行一個LiveReload服務器。 開始應用程序以前,請確保沒有其餘LiveReload服務器正在運行。 若是從IDE啓動多個應用程序,則只有第一個應用程序將支持LiveReload。

20.4 全局設置

您能夠經過向 $HOME 文件夾添加名爲.spring-boot-devtools.properties的文件來配置全局devtools設置(請注意文件名以「.」開頭)。 添加到此文件的任何屬性將適用於您的計算機上使用devtools的全部Spring Boot應用程序。 例如,要配置從新啓動以始終使用觸發器文件,您能夠添加如下內容:

~/.spring-boot-devtools.properties.

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

20.5遠程應用

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

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

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

spring.devtools.remote.secret=mysecret

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

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

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

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

例如,若是您使用Eclipse或STS,而且有一個名爲my-app的項目已部署到Cloud Foundry,則能夠執行如下操做:

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

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

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

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

建議使用https//做爲鏈接協議,以便流量被加密,防止密碼被攔截。

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

20.5.2 遠程更新

遠程客戶端將以與本地相同的方式監視應用程序類路徑的更改。 任何更新的資源將被推送到遠程應用程序,而且(若是須要的話)觸發從新啓動。 若是您正在迭代使用您當地沒有的雲服務的功能,這可能會很是有用。 一般,遠程更新和從新啓動比徹底重建和部署週期要快得多。

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

20.5.3 遠程調試隧道

在遠程應用程序診斷問題時,Java遠程調試很是有用。 不幸的是,當您的應用程序部署在數據中心以外時,並不老是可以進行遠程調試。 若是您正在使用基於容器的技術(如Docker),遠程調試也可能難以設置。

爲了幫助解決這些限制,devtools支持基於HTTP隧道的傳輸遠程調試傳輸。 遠程客戶端在端口8000上提供本地服務器,您能夠鏈接遠程調試器。 創建鏈接後,經過HTTP將調試數據發送到遠程應用程序。 若是要使用其餘端口,可使用spring.devtools.remote.debug.local-port屬性更改。

您須要確保遠程應用程序啓用遠程調試啓用。 一般能夠經過配置JAVA_OPTS來實現。 例如,使用Cloud Foundry,您能夠將如下內容添加到manifest.yml中:

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

請注意,您不須要將 address=NNNN 選項傳遞給-Xrunjdwp。 若是省略Java將隨機選擇一個的空閒端口。

經過網絡調試遠程服務可能很慢,您可能須要在IDE中增長超時時間。 例如,在Eclipse中,您能夠從Preferences…中選擇Java→Debug ,並將Debugger timeout (ms)更改成更合適的值(大多數狀況下,60000能夠正常工做)。

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

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

可執行的jar可用於生產部署。 因爲它們是相互獨立的,它們也很是適合基於雲的部署。

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

22. 接下來應該讀什麼

您如今應該很好地瞭解如何使用Spring Boot以及您應該遵循的一些最佳作法。 您如今能夠深刻了解特定的Spring Boot功能,或者您能夠跳過這部分,真的閱讀Spring Boot的「生產環境準備」方面。

相關文章
相關標籤/搜索