第三單元.使用SpringBoot
本節將更詳細地介紹如何使用SpringBoot。它覆蓋的主題有構建系統,自動配置以及如何運行你的應用。我們也會提供一些SpringBoot的最佳實踐。儘管關於SpringBoot沒有什麼特別之處(它只是另一個你可以使用的庫),但是有一些建議,當你遵循了,可以讓你的開發更簡單一些。
如果你剛開始接觸SpringBoot,你應該先閱讀入門指南,然後進入這個章節。
13. 構建系統
強烈建議你選擇一個構建系統,支持依賴管理並且可以使用發佈到“MavenCentral”倉庫的工程包。我們建議你選擇Maven或者Gradle。SpringBoot也可以支持其它構建系統(例如:Ant),不過它們並沒有得到特別好的支持。
13.1 依賴管理
任何一個SpringBoot正式版本都會提供一份它支持的依賴關係的精選列表。實際上,你不需要提供版本號給任何在你構建配置文檔中的依賴,SpringBoot會進行管理。當你升級SpringBoot時,這些依賴項也會以一致的方式升級。
如果你需要,你可以指定版本來覆蓋SpringBoot建議的版本。
精選列表包含可與SpringBoot一起使用的所有spring模塊以及完善的第三方庫列表。該列表作爲可與Maven和Gradle一起使用的標準材料清單。
每一個正式版本SpringBoot都關聯基礎版本的SpringFramework。我們強烈建議你不要指定其版本。
13.2 Maven
Maven用戶可以繼承spring-boot-starter-parent項目以獲得合理的默認配置。該父項目提供以下的特徵:
- Java1.8作爲默認編譯器版本
- 源碼編碼格式爲UTF-8
- 一個依賴管理部分,繼承自spring-boot-dependenciespom,管理公共依賴的版本。當你自己的pom中使用,這個依賴管理讓你忽略這些依賴項的標籤
- 使用repackage執行ID來實現一個可執行的repackage目標。
- 智能的資源過濾
- 智能的插件配置(exec插件,Git Commit ID和share)
- 針對application.properties和application.yml 包括特定於配置文件的文件(例如application-dev.properties和 application-dev.yml)進行明智的資源過濾
請注意,自從application.properties和application.yml文件使用Spring風格的佔位符(${}),Maven過濾改用(@…@)當佔位符。(你可以設置屬性來覆蓋Maven的resource.delimiter屬性)
13.2.1 繼承自Starter Parent
要將你的項目配置爲繼承自spring-boot-starter-parent,設置parent如下:
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.5.RELEASE</version>
</parent>
你只需要在這個依賴指定SpringBoot版本。如果你導入其它的啓動器,你可以安全的忽略版本。
使用該設置,你還可以通過覆蓋自己項目中的屬性來覆蓋各個依賴項。例如,要升級到另一個SpringDataReleasetrain,你可以將以下內容添加到你的pom.xml:
<properties>
<spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version>
</properties>
檢查spring-boot-dependencies-pom 獲取支持的屬性列表。
13.2.2 在沒有Parent Pom下使用SpringBoot
並不是所有人都喜歡繼承spring-boot-starter-parent-POM。你可能需要使用你們公司的標準parent或者你可能希望顯式聲明所有Maven配置
如果你不希望使用spring-boot-starter-parent,你仍然可以通過dependencyManagement(不是插件管理)獲取好處,使用scopre=import依賴,如下:
<dependencyManagement>
<dependencies>
<dependency>
<!-- Import dependency management from Spring Boot -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
如上所述,在前面的示例步驟沒有讓你使用屬性來覆蓋個別的依賴。爲了取得相同的結果,你需要添加dependencyManagement在你的項目中,在spring-boot-dependencies依賴之前添加你的依賴。例如,要升級pringDataReleasetrain,你可以添加以下元素到你的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>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.1.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在前面的案例中,我們指定了BOM,但是可以以相同的方式覆蓋任何依賴項類型。
13.2.3 使用SpringBoot Maven插件
SpringBoot包含一個可以打包項目作爲可執行jar包的Maven插件。如果你要使用它,可以添加插件到你的部分,如下面顯示的案例:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
如果你使用了spring-boot-starter-parent-pom,則只需要添加插件。你不需要做任何配置,除非你要修改parent定義的設置。
13.3 Gradle
要了解有關將Spring Boot與Gradle結合使用的信息,請參閱Spring Boot的Gradle插件的文檔::
13.4 Ant
可以使用Apache Ant + Ivy構建SpringBoot項目。該spring-boot-antlib的antlib模塊還可以幫助Ant創建可執行的JAR文件。
爲了聲明依賴關係,典型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="2.1.5.RELEASE" />
<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>
如果您不想使用該spring-boot-antlib模塊,請參見Section 91.9, “Build an Executable Archive from Ant without Using spring-boot-antlib”
13.5 啓動器
啓動器是一組方便的依賴關係描述符,你可以將其包含在應用程序中。你可以一站式獲取所有spring以及關聯的技術,不需要去搜索示例代碼和複製粘貼依賴描述符。例如,如果你想要開始使用Spring和JPA來訪問數據庫,包含spring-boot-starter-data-jpa依賴項到你的項目。
啓動器包含一系列項目啓動,快速運行,一致性的依賴項,支持管理傳遞性依賴的集合。
名字叫什麼
所有官方啓動器遵循相似命名規則;spring-boot-starter-*,其中 *是特定類型的應用程序。這種命名結構在你需要尋找啓動器時提供幫助。Maven集成在許多IDE中,使你可以按名稱搜索依賴項。例如,在安裝了適當的Eclipse或STS插件的情況下,你可以在POM編輯器按ctrl-space,然後鍵入“spring-boot-starter”以獲取完整列表。
如“創建你自己的啓動器”部分中所述,第三方啓動器不應以spring-boot開頭,它被保留用於官方的springboot工程包。相反,第三方啓動器通常以項目的名稱開始。例如,一個第三方啓動器項目稱爲thirdpartyproject,通常命名爲thirdpartyproject-spring-boot-starter。
SpringBoot在該org.springframework.boot組下提供了以下應用程序啓動器 :
Name | Description | Pom |
---|---|---|
spring-boot-starter | 核心啓動器,包括支持自動配置,日誌記錄和YAML | Pom |
spring-boot-starter-activemq | 使用Apache ActiveMQ的JMS消息通知啓動器 | Pom |
spring-boot-starter-amqp | 使用Spring AMQP和Rabbit MQ的啓動器 | Pom |
spring-boot-starter-aop | 使用Spring AOP和AspectJ進行面向切面編程的啓動器 | Pom |
spring-boot-starter-artemis | 使用Apache Artemis的JMS消息通知啓動器 | Pom |
spring-boot-starter-batch | 使用Spring Batch的啓動器 | Pom |
spring-boot-starter-cache | 使用Spring Framework緩存支持的啓動器 | Pom |
spring-boot-starter-cloud-connectors | 使用Spring Cloud Connectors的啓動器,可簡化與Cloud Foundry和Heroku等雲平臺中服務的連接 | Pom |
spring-boot-starter-data-cassandra | 使用Cassandra分佈式數據庫和Spring Data Cassandra的啓動器 | Pom |
spring-boot-starter-data-cassandra-reactive | 使用Cassandra分佈式數據庫和Spring Data Cassandra Reactive的啓動器 | Pom |
spring-boot-starter-data-couchbase | 使用Couchbase面向文檔的數據庫和Spring Data Couchbase的啓動器 | Pom |
spring-boot-starter-data-couchbase-reactive | 使用Couchbase面向文檔的數據庫和Spring Data Couchbase Reactive的啓動器 | Pom |
spring-boot-starter-data-elasticsearch | 使用Elasticsearch搜索和分析引擎以及Spring Data Elasticsearch的啓動器 | Pom |
spring-boot-starter-data-jdbc | 使用Spring Data JDBC的啓動器 | Pom |
spring-boot-starter-data-jpa | 將Spring Data JPA與Hibernate結合使用的啓動器 | Pom |
spring-boot-starter-data-ldap | 使用Spring Data LDAP的啓動器 | Pom |
spring-boot-starter-data-mongodb | 使用MongoDB面向文檔的數據庫和Spring Data MongoDB的啓動器 | Pom |
spring-boot-starter-data-mongodb-reactive | 使用MongoDB面向文檔的數據庫和Spring Data MongoDB Reactive的啓動器 | Pom |
spring-boot-starter-data-neo4j | 使用Neo4j圖形數據庫和Spring Data Neo4j的啓動器 | Pom |
spring-boot-starter-data-redis | 使用Redis鍵值數據存儲與Spring Data Redis和Lettuce客戶端的啓動器 | Pom |
spring-boot-starter-data-redis-reactive | 將Redis鍵值數據存儲與Spring Data Redis Reacting和Lettuce客戶端一起使用的啓動器 | Pom |
spring-boot-starter-data-rest | 使用Spring Data REST通過REST公開Spring數據存儲庫的啓動器 | Pom |
spring-boot-starter-data-solr | 將Apache Solr搜索平臺與Spring Data Solr結合使用的啓動器 | Pom |
spring-boot-starter-freemarker | 使用FreeMarker視圖構建MVC Web應用程序的 | Pom |
spring-boot-starter-groovy-templates | 使用Groovy模板視圖構建MVC Web應用程序的啓動器 | Pom |
spring-boot-starter-hateoas | 使用Spring MVC和Spring HATEOAS構建基於超媒體的RESTful Web應用程序的啓動器 | Pom |
spring-boot-starter-integration | 使用Spring Integration的啓動器 | Pom |
spring-boot-starter-jdbc | 結合使用JDBC和HikariCP連接池的啓動器 | Pom |
spring-boot-starter-jersey | 使用JAX-RS和Jersey構建RESTful Web應用程序,代替spring-boot-starter-web的啓動器 | Pom |
spring-boot-starter-jooq | 使用jOOQ訪問SQL數據庫的啓動器。替代spring-boot-starter-data-jpa或spring-boot-starter-jdbc | Pom |
spring-boot-starter-json | 讀寫JSON的啓動器 | Pom |
spring-boot-starter-jta-atomikos | 使用Atomikos的JTA交易的啓動器 | Pom |
spring-boot-starter-jta-bitronix | 使用Bitronix的JTA交易的啓動器 | Pom |
spring-boot-starter-mail | 使用Java Mail和Spring Framework的電子郵件發送支持的啓動器 | Pom |
spring-boot-starter-mustache | 使用Mustache視圖構建Web應用程序的啓動器 | Pom |
spring-boot-starter-oauth2-client | 使用Spring Security的OAuth2或OpenID Connect客戶端功能的啓動器 | Pom |
spring-boot-starter-oauth2-resource-server | 使用Spring Security的OAuth2資源服務器功能的啓動器 | Pom |
spring-boot-starter-quartz | 使用Quartz Scheduler的啓動器 | Pom |
spring-boot-starter-security | 使用Spring Security的啓動器 | Pom |
spring-boot-starter-test | 用於使用包括JUnit,Hamcrest和Mockito在內的庫測試Spring Boot應用程序的啓動器 | Pom |
spring-boot-starter-thymeleaf | 使用Thymeleaf視圖構建MVC Web應用程序的啓動器 | Pom |
spring-boot-starter-validation | 通過Hibernate Validator使用Java Bean驗證的啓動器 | Pom |
spring-boot-starter-web | 使用SpringMVC構建Web(包括RESTful)應用程序的啓動器。使用Tomcat作爲默認的嵌入式容器 | Pom |
spring-boot-starter-web-services | 使用Spring Web Services的啓動器 | Pom |
spring-boot-starter-webflux | 使用Spring Framework的Reactive Web支持構建WebFlux應用程序的啓動器 | Pom |
spring-boot-starter-websocket | 使用Spring Framework的WebSocket支持構建WebSocket應用程序的啓動器 | Pom |
除了應用程序啓動器,以下啓動器可用於添加生產就緒功能:
Name | Description | Pom |
---|---|---|
spring-boot-starter-actuator | 使用Spring Boot的Actuator的啓動器,它提供了生產就緒功能,可幫助您監視和管理應用程序 | Pom |
Finally, Spring Boot also includes the following starters that can be used if you want to exclude or swap specific technical facets:
最後,Spring Boot還包括以下啓動器,如果你想排除或交換特定的技術方面,可以使用這些啓動器:
Name | Description | Pom |
---|---|---|
spring-boot-starter-jetty | 使用Jetty作爲嵌入式servlet容器的啓動器。替代spring-boot-starter-tomcat | Pom |
spring-boot-starter-log4j2 | 使用Log4j2進行日誌記錄的啓動器。替代spring-boot-starter-logging | Pom |
spring-boot-starter-logging | 使用Logback進行日誌記錄的啓動器。默認記錄啓動器 | Pom |
spring-boot-starter-reactor-netty | 使用Reactor Netty作爲嵌入式反應式HTTP服務器的啓動器 | Pom |
spring-boot-starter-tomcat | 用於將Tomcat用作嵌入式Servlet容器的啓動器。使用spring-boot-starter-web默認使用的servlet容器啓動器 | Pom |
spring-boot-starter-undertow | 使用Undertow作爲嵌入式servlet容器的啓動器。替代spring-boot-starter-tomcat | Pom |
有關社區貢獻的其它啓動器列表,可以查看GitHub中spring-boot-starters模塊的README文件
14. 結構化你的代碼
springboot不要求任何特定的代碼佈局就可以工作。但是有一些最佳實踐可以提供幫助。
14.1 使用“default”包
當一個類文件不包含package的申明時,它被認爲在“默認包”中。通常不建議使用“默認包”,應該避免使用。這可能導致特別的問題,當springboot應用使用@ComponentScan,@EntityScan,或者@SpringBootApplication註解,從每一個jar中讀取每一個類。
我們建議你遵循Java建議的程序包命名約定,並使用反向域名(例如com.example.project)。
14.2 定位主應用類
我們通常建議你將主應用類放置在其它類之上的根包。@SpringBootApplication註解經常被放置在你的主類,而且它意味着爲指定項目定義一個基礎“搜索包”。例如,如果你寫一個JPA應用程序,該包的@SpringBootApplication註解類將會去搜索@Entity項目。使用根包還允許在你的項目上組件掃描。
如果你不想使用@SpringBootApplication,它導入了定義該行爲的@EnableAutoConfiguration和@ComponentScan註解,因此你也可以使用它。
以下列表顯示了典型的佈局:
com
+- example
+- myapplication
+- Application.java
|
+- customer
| +- Customer.java
| +- CustomerController.java
| +- CustomerService.java
| +- CustomerRepository.java
|
+- order
+- Order.java
+- OrderController.java
+- OrderService.java
+- OrderRepository.java
該Application.java文件將聲明main方法以及basic方法, @SpringBootApplication如下所示:
package com.example.myapplication;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
15. 配置類
springboot支持基於Java的配置。儘管它可以通過XML使用SpringApplication,我們通常建議你首先使用單一@Configuration類。通常,定義main方法的類都會@Configuration的最佳首選。
很多發佈到互聯網上的spring配置示例使用了XML配置,如果可以,希望可以嘗試等同的基於Java配置。搜索Enable*註解可能是一個很好的起點。
15.1 入額外的配置類
你不需要放置你所有的@Configuration在一個類。@Import註解可以被用來導入額外的配置類。,你可以使用@ComponentScan去自動獲得所有SpringComponents,包含@Configuration類。
15.2 導入XML配置
如果你一定需要使用基於XML配置,我們建議你依然使用@Configuration啓動。你可以使用@ImportResource註解來加載XML配置文件。
16. 自動配置
springboot自動配置嘗試去基於你添加的依賴jar包來自動配置你的spirng應用。例如,如果HSQLDB在你的classpath,而且你沒有手動配置任何數據庫連接,之後spirngboot會自動配置一個基於內存的數據庫。
你需要選擇通過添加@EnableAutoConfiguration或者@SpringBootApplication註解在你一個@Configuation類中來選擇自動配置。
你應該永遠只添加一個@SpringBootApplication或者@EnableAutoConfiguration註解。我們通常建議在你主要的@Configuration類上添加個@SpringBootApplication或者@EnableAutoConfiguration。
16.1 逐步替換自動配置
自動配置是非入侵的。在任何時刻,你可以開始定義你自己的配置來替換自動配置的特定部分。例如,如果你要添加你自己的DataSourceBean,默認的嵌入式數據庫支持將退出。
如果你需要找出,自動配置在當前應用了哪些和爲什麼用,開啓你應用的-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,你可以使用@EnableAutoConfiguration的excludeName屬性指定其完全限定名稱來代替。最後,你還可以使用spring.autoconfigure.exclude屬性來控制要排除的自動配置類的列表 。
- @EnableAutoConfiguration的excludeName屬性
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
import org.springframework.context.annotation.*;
@Configuration
@SpringBootApplication(excludeName = {"org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration"})
public class MyConfiguration {
}
- spring.autoconfigure.exclude
# 多值使用,分隔
spring.autoconfigure.exclude=org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
你可以在註釋級別和使用屬性來定義排除項。
17. Spring Beans和依賴注入
你可以自由使用任何標準的spring框架技術來定義你的beans和他們的注入依賴。爲簡單起見,我們經常發現使用@ComponentScam(去查找你的beans)和使用@Autowired(執行結構函數注入)效果很好。
如果你是按照上面的建議構造代碼(放置你的應用類在根包中),你可以添加@ComponentScan不需要任何參數。所有你的應用組件(@Component,@Service,@Repository,@Controller)都會自動註冊到spring beans。
以下案例展示一個@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註解
許多springboot開發人員喜歡他們的應用使用自動配置,組件掃描和在“應用程序類”上允許定義額外的配置。單個SpringBootApplication註解可以啓用這三個特徵,即:
- 啓動spingboot的自動配置機制
- 開啓在應用程序所在的包上進行@Component掃描(參考最佳實踐)
- 允許在上下文註冊額外的bean或導入額外的配置類
@SpringBootApplication註解等價於使用@Configuration,@EnableAutoConfiguration和@ComponentScan的默認屬性,如以下示例展示:
package com.example.myapplication;
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屬性。
這些功能都不是強制性的,你可以選擇用它啓用的任何功能替換此單個註釋。例如,你可能不想在應用程序中使用組件掃描:
package com.example.myapplication;
import org.springframework.boot.SpringApplication;
import org.springframework.context.annotation.ComponentScan
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
@Configuration
@EnableAutoConfiguration
@Import({ MyConfig.class, MyAnotherConfig.class })
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
在這個示例中,Application和任何springboot應用一樣,除了有註釋@Component的類沒有被自動檢測到和顯示導入用戶定義的beans(查看@Import)
19. 運行你的應用
其中一個最大的優勢是你可以打包你的應用程序作爲一個jar,並且使用內嵌的HTTP服務,你可以像運行其它應用程序一樣,運行你的應用程序。調試springboot應用程序一樣很簡單。你不需要特定的IDE插件或擴展。
這個章節只介紹打包jar。如果你選擇打包你的應用程序作爲一個war文件,你應該參考服務器和IDE文檔。
19.1 從一個IDE運行
你可以像通過IDE運行簡單java應用一樣來運行springboot應用。無論如何,你首先需要導入你的項目。導入步驟取決於你的IDE和構建系統。大部分IDE可以直接導入Maven項目。例如,Eclipse用戶可以從File菜單選擇Import…->Existing Maven Projects
如果無法直接導入你的項目到你的IDE,你可能要允許使用構建插件來生成IDE元數據。Maven包含Eclipse和IDEA的插件。Gradle爲多種IDE提供插件。
如果你不小心運行了兩次web應用,你看到一個“端口已經被使用”的異常。STS(springtoolsuite)用戶可以使用Relaunch按鈕而不是Run按鈕,來確認任何已存在的實例被關閉。
19.2 運行一個打包的應用程序
如果你使用Spring Boot Maven或Gradle插件去創建一個可執行jar,你可以使用java -jar來運行你的應用程序,如下所示:
$ java -jar target/myapplication-0.0.1-SNAPSHOT.jar
它也可以支持遠程調式模式下運行打包的應用程序。這樣做讓你的包應用附加調試器,如下面的示例所示:
$ java -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n -jar target/myapplication-0.0.1-SNAPSHOT.jar
19.3 使用Maven插件
springboot Maven插件包含run命令,可以用來快速編譯和運行你的應用程序。應用程序以分解的形式運行,就像他們在你的IDE中所做的一樣。下面案例展示經典的Maven命令去運行springboot應用程序:
$ mvn spring-boot:run
你可能也想使用MAVEN_OPTS操作系統環境變量,按以下示例展示:
$ export MAVEN_OPTS=-Xmx1024m
19.4 使用Gradle插件
springboot Gradle插件也包含bootRun任務,可以用它以分解的形式來運行你的應用程序。當你應用org.springframework.boot和java插件,都會添加bootRun任務,如下所示:
$ gradle bootRun
你可能也想使用JAVA_OPTS操作系統環境變量,按以下示例展示:
$ export JAVA_OPTS=-Xmx1024m
19.5 熱交換
因爲springboot應用程序只是簡單的java應用程序,JVM熱交換應該是開箱即用。JVM熱交換在一定程度上受到它可以替換的字節碼的限制。對於更完整的解決方案, 可以使用JRebel。
spring-boot-devtools模塊包含支持快速重啓應用程序。有關詳細信息,請參見本章後面的Chapter20. Developer Tools章節和熱交換操作細節。
20. 開發人員工具
springboot包含一些額外的工具,來讓應用程序開發有一個更愉快的體驗。spring-boot-devtools模塊可以包含在任意項目中來提供額外的開發時功能。要包含devtools支持,添加該模塊依賴到你的構件中,以下介紹Maven和Gradle:
- Maven.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
- Gradle.
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
}
dependencies {
developmentOnly("org.springframework.boot:spring-boot-devtools")
}
當你運行一個完全打包的應用程序,將自動禁用開發者工具。如果你的應用程序時通過java-jar或從其它特殊的類加載器啓動,它將被認爲是“生產應用”。如果對你不適用(如果你是通過容器來運行你的應用程序),考慮排除devtools或設置-Dspring.devtools.restart.enabled=false系統屬性。
在Maven中將依賴項標記爲可選,或在Gradle中使用自定義的“developmentOnly”配置(如上所示)是一種最佳做法,可防止將devtools過渡應用到使用項目的其他模塊。
重新打包的存檔默認情況下不包含devtools。如果要使用某個遠程devtools功能,則需要禁用excludeDevtoolsbuild屬性以包含它。Maven和Gradle插件均支持該屬性。
20.1 屬性默認值
springboot支持一些庫使用緩存來提高性能。例如,模板引擎緩存已編譯的模板,以避免重複解析模板文件。而且,SpringMVC可以在提供靜態資源時向響應添加HTTP緩存標頭。
儘管緩存在生產中非常有益,但在開發過程中可能適得其反,從而使你無法看到自己剛剛在應用程序中所做的更改。因此,默認情況下,spring-boot-devtools禁用緩存選項。
緩存選項通常通過配置application.properties文件來設定。例如,Thymeleaf提供spring.thymeleaf.cache屬性。spring-boot-devtools模塊無需自動設置這些屬性,而是自動應用合理的開發時配置。
因爲在開發SpringMVC和SpringWebFlux應用程序時需要有關Web請求的更多信息,所以開發者工具將啓用DEBUG日誌web記錄組的日誌記錄。這將爲你提供有關傳入請求,正在處理的處理程序,響應結果等的信息。如果你希望記錄所有請求的詳細信息(包括潛在的敏感信息),則可以打開spring.http.log-request-details配置屬性。
如果你不想屬性使用默認值,可以在你的application.properties設置spring.devtools.add-properties=false
有關devtools應用的屬性的完整列表,請參見DevToolsPropertyDefaultsPostProcessor。
static {
Map<String, Object> properties = new HashMap<>();
properties.put("spring.thymeleaf.cache", "false");
properties.put("spring.freemarker.cache", "false");
properties.put("spring.groovy.template.cache", "false");
properties.put("spring.mustache.cache", "false");
properties.put("server.servlet.session.persistent", "true");
properties.put("spring.h2.console.enabled", "true");
properties.put("spring.resources.cache.period", "0");
properties.put("spring.resources.chain.cache", "false");
properties.put("spring.template.provider.cache", "false");
properties.put("spring.mvc.log-resolved-exception", "true");
properties.put("server.error.include-stacktrace", "ALWAYS");
properties.put("server.servlet.jsp.init-parameters.development", "true");
properties.put("spring.reactor.stacktrace-mode.enabled", "true");
PROPERTIES = Collections.unmodifiableMap(properties);
}
20.2 自動重啓
只要類路徑上的文件發生更改,使用spring-boot-devtools的應用程序就會自動重新啓動。當你通過IDE工作時,這個可能是一個有用的功能,因爲它爲代碼更改提供了非常快速的反饋循環。默認情況下,將監視類路徑上指向文件夾的任何條目的更改。請注意,某些資源(例如靜態資產和視圖模板)不需要重新啓動應用程序。
觸發重啓
當DevTools監視類路徑資源時,觸發重啓的唯一方法是更新類路徑。導致類路徑更新的方式取決於你使用的IDE。在Eclipse中,保存修改後的文件將導致類路徑被更新並觸發重新啓動。在IntelliJ IDEA中,構建項目(Build -> Build Project)具有相同的效果。
只要啓用了分叉,你還可以使用受支持的構建插件(Maven和Gradle)來啓動應用程序,因爲DevTools需要隔離的應用程序類加載器才能正常運行。默認情況下,Gradle和Maven在類路徑上檢測到DevTools時會這樣做。
自動重啓效果很好,當配合LiveReload使用時。查看LiveReload章節細節。如果你使用JRebel,自動重啓將失效,而支持動態類加載。其它devtools特性(例如LiveReload和屬性覆蓋)依然可以使用。
DevTools依賴於應用程序上下文的關閉掛鉤在重新啓動期間將其關閉。如果你禁用了關閉掛鉤(SpringApplication.setRegisterShutdownHook(false)),它將無法正常工作。
當決定類路徑中的條目發生變化時是否應該觸發重新啓動時,DevTools自動忽略命名的項目spring-boot,spring-boot-devtools,spring-boot-autoconfigure,spring-boot-actuator,和spring-boot-starter。
DevTools需要使用的ApplicationContext去定製ResourceLoader。如果你的應用程序已經提供了,它將被包裝。不支持直接覆蓋ApplicationContext的getResource方法。
重啓 vs 重載
springboot提供的重啓技術通過使用兩個類加載器來工作。不變的類(例如,來自第三方jar的類)將被加載到基類加載器中。你正在積極開發的類將加載到重新啓動類加載器中。重新啓動應用程序時,將丟棄重新啓動類加載器,並創建一個新的類加載器。這種方法意味着應用程序的重啓通常比“冷啓動”要快得多,因爲基本類加載器已經可用並已填充。
如果發現重新啓動對於你的應用程序而言不夠快,或者遇到類加載問題,則可以考慮重新加載技術,例如ZeroTurnaround的 JRebel。這些工作是通過在裝入類時重寫它們,使它們更易於重新裝入。
20.2.1 記錄條件評估中的更改
默認情況下,每次應用程序重新啓動時,都會記錄一個報告,其中顯示了條件評估增量。該報告顯示了在進行諸如添加或刪除bean以及設置配置屬性之類的更改時對應用程序自動配置的更改。
要禁用報告的日誌記錄,請設置以下屬性:
spring.devtools.restart.log-condition-evaluation-delta=false
20.2.2 排除資源
某些資源在更改時不一定需要觸發重新啓動。例如,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.3 監控其它路徑
當你修改了不在類路徑下的文件,可能也想你的應用重啓或重載。爲此,使用spring.devtools.restart.additional-paths屬性去配置額外要監控改變的路徑。你可以使用前面描述的spring.devtools.restart.exclude來控制其他路徑下的更改是觸發完全重新啓動還是實時重新加載。
20.2.4 禁用重啓
如果你不想使用重啓特性,你可以使用spring.devtools.restart.enabled屬性來禁用它。在大多數情況下,你可以在你的application.properties中設置這個屬性(這樣做仍會初始化重新啓動類加載器,但它不會監視文件更改)。
如果你需要徹底禁用重啓的支持(例如,因爲它不適用於特定的庫),你需要去設置System的屬性spring.devtools.restart.enabled=false,在調用pringApplication.run(…)之前,如下案例所示:
public static void main(String[] args) {
System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(MyApp.class, args);
}
20.2.5 使用觸發器文件
如果使用持續編譯更改文件的IDE,則可能更喜歡僅在特定時間觸發重新啓動。爲此,你可以使用“觸發文件”,這是一個特殊文件,當你要實際觸發重新啓動檢查時必須對其進行修改。更改文件只會觸發檢查,並且只有在Devtools檢測到必須執行某些操作時纔會重新啓動。可以手動或使用IDE插件來更新觸發文件。
要使用觸發文件,請將spring.devtools.restart.trigger-file屬性設置爲觸發文件的路徑。
你可能希望將其設置spring.devtools.restart.trigger-file爲全局設置,以便所有項目都以相同的方式運行。
20.2.6 自定義重啓類加載器
如前面Restart vs Reload章節所述,重啓功能是通過使用兩個類加載器實現的。大部分應用,此方法效果很好。但是,有時可能會導致類加載問題。
默認情況下,IDE中任何打開的項目都使用“重新啓動”類加載器加載,而任何常規.jar文件都使用“基本”類加載器加載。如果你在多模塊項目上工作,並且並非每個模塊都導入到IDE中,則可能需要自定義內容。爲此,你可以創建一個META-INF/spring-devtools.properties文件。
該spring-devtools.properties文件可以包含以restart.exclude和restart.include開頭的屬性。該include元素是應該被拉高到“重啓”類加載器的項目,以及exclude要素是應該向下推入“基礎”類加載器的項目。該屬性的值是一個應用於類路徑的正則表達式模式,如以下示例所示:
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.7 已知限制
重新啓動功能不適用於通過使用標準反序列化的對象ObjectInputStream。如果你需要反序列化的數據,你可能需要使用Spring的ConfigurableObjectInputStream結合Thread.currentThread().getContextClassLoader()。
不幸的是,一些第三方庫在不考慮上下文類加載器的情況下反序列化。如果發現這樣的問題,則需要向原始作者請求修復。
20.3 LiveReload
spring-boot-devtools模塊包括一個嵌入式LiveReload服務器,該服務器可用於在更改資源時觸發瀏覽器刷新。可從livereload.com免費獲得適用於Chrome,Firefox和Safari的LiveReload瀏覽器擴展 。
如果當你的應用程序運行時,你不想啓動LiveReload服務,可以設置spring.devtools.livereload.enabled=false。
同一時間你只能運行一個LiveReload服務。在啓動你的應用程序之前,確保沒有其它的LiveReload服務在運行。如果你多次從IDE啓動應用程序,只有第一個LiveReload支持。
20.4 全局設定
你可以通過添加一個文件名爲spring-boot-devtools.properties你的$HOME文件夾(注意:文件名開頭“.”),來配置全局devtools設置 。添加到此文件的任何屬性都將應用於使用devtools的計算機上的所有springboot應用程序。例如,要將重啓配置爲始終使用觸發文件,你可以添加以下屬性:
~/.spring-boot-devtools.properties.
spring.devtools.reload.trigger-file=.reloadtrigger
激活的配置文件.spring-boot-devtools.properties不會影響特定於配置文件的配置文件的加載。
20.5 遠程應用
springboot開發人員工具不僅限於本地開發。遠程運行應用程序時,你還可以使用多種功能。選擇加入遠程支持。要啓用它,你需要確保已將devtools其包含在重新打包的存檔中,如以下清單所示:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludeDevtools>false</excludeDevtools>
</configuration>
</plugin>
</plugins>
</build>
然後,你需要設置一個spring.devtools.remote.secret屬性,如以下示例所示:
spring.devtools.remote.secret=mysecret
spring-boot-devtools在遠程應用程序上啓用存在安全風險。你永遠不要在生產部署上啓用支持。
遠程devtools支持分爲兩個部分:接受連接的服務器端端點和在IDE中運行的客戶端應用程序。spring.devtools.remote.secret設置屬性後,將自動啓用服務器組件。客戶端組件必須手動啓動。
20.5.1 運行遠程客戶端應用程序
遠程客戶端應用程序旨在在你的IDE中運行。你需要org.springframework.boot.devtools.RemoteSpringApplication使用與所連接的遠程目錄相同的類路徑來運行。應用程序的唯一必需參數是它連接到的遠程URL。
例如,如果你使用的是Eclipse或STS,並且有一個my-app已部署到Cloud Foundry的項目,則應執行以下操作:
- 選擇Run Configurations…從Run菜單。
- 創建一個新的Java Application “launch configuration”。
- 瀏覽該my-app項目。
- 使用org.springframework.boot.devtools.RemoteSpringApplication作爲主類。
- 添加https://myapp.cfapps.io到Program arguments(或任何你的遠程URL)。
正在運行的遠程客戶端可能類似於以下清單:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \
\\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) )
' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / /
=========|_|==============|___/===================================/_/_/_/
:: Spring Boot Remote :: 2.1.5.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 遠程更新
遠程客戶端以與本地重新啓動相同的方式監視應用程序類路徑中的更改。任何更新的資源都會推送到遠程應用程序,並且(如果需要)會觸發重新啓動。如果你迭代使用本地沒有的雲服務的功能,這將很有幫助。通常,遠程更新和重新啓動比完整的重建和部署週期要快得多。
僅在遠程客戶端正在運行時監視文件。如果在啓動遠程客戶端之前更改文件,則不會將其推送到遠程服務器。
21. 打包你的生產申請
可執行jar可以用於生產部署。由於它們是獨立的,因此它們也非常適合基於雲的部署。
對於其他“生產準備就緒”功能,例如運行狀況,審覈和度量標準REST或JMX端點,請考慮添加spring-boot-actuator。有關詳細信息,請參見 第五部分“Spring Boot執行器:生產就緒功能”。
22. 接下來閱讀什麼
現在,你應該瞭解如何使用springboot以及應遵循的一些最佳實踐。現在,你可以繼續深入瞭解特定的springboot功能,或者可以跳過並閱讀有關springboot的“生產就緒”方面的信息。