本節(jié)將詳細(xì)介紹如何使用Spring Boot, 它包含了諸如構(gòu)建系統(tǒng),自動配置以及怎么運行你的程序這些主題。我們還將介紹一些Spring Boot的最佳實踐。盡管Spring Boot沒什么特別的(它只是您可以使用的另一個庫),但是有一些建議可以使您的開發(fā)過程更輕松一些。
如果你是從Spring Boot開始的,那么在深入了解之前,您應(yīng)該閱讀入門指南
3.1 構(gòu)建系統(tǒng)
我們強烈推薦您選擇一個支持依賴管理的構(gòu)建系統(tǒng),可以讓你使用發(fā)布到Maven中央倉庫的組件。我們建議您使用Maven或Gradle。可以使Spring Boot與其它構(gòu)建系統(tǒng)(例如Ant)一起使用,但是它們并沒有得到很好的支持。
3.3.1 依賴管理
每個Spring Boot版本都提供了他所支持的依賴關(guān)系列表,實踐中,您不用在您的構(gòu)建配置上提供任何依賴的版本,因為Spring Boot已經(jīng)幫你管理了。當(dāng)你升級Spring Boot時,它的依賴也一并升級了。
當(dāng)你需要時,你仍然可以聲明版本來覆蓋Spring Boot推薦的版本。
精選列表包含可與Spring Boot一起使用的所有spring模塊以及完善的第三方庫列表。 該列表是可與Maven和Gradle一起使用的標(biāo)準(zhǔn)依賴清單(spring-boot-dependencies)。
每個Spring Boot穩(wěn)定版本都和一個Spring Framework基礎(chǔ)版本相關(guān)聯(lián),我們強烈建議您不要聲明它的版本。
3.1.2 Maven
Maven用戶可以繼承spring-boot-starter-parent來獲取一些合理的默認(rèn)值,該Parent項目提供了下列功能:
- Java 1.8作為默認(rèn)編譯級別
- UTF-8編碼
- 一個繼承自spring-boot-dependencies pom文件的依賴管理塊,它管理了通用依賴的版本。這個依賴管理讓你省略在pom文件使用的那些依賴的<version>標(biāo)簽
- 以repackage來實現(xiàn)重新打包目標(biāo)的執(zhí)行
- 智能的文件過濾
- 合理的插件配置(exec插件,Git提交Id和Shade)
- 對application.properties和application.yml進行智能的資源過濾,包括特定于配置文件的文件(例如,application-dev.properties和application-dev.yml)
注意,由于application.properties和application.yml文件接受Spring樣式的占位符(${...}),因此Maven過濾已更改為使用@...@占位符(您可以通過設(shè)置一個名為resource.delemiter的Maven屬性來覆蓋它)
繼承啟動器
通過繼承spring-boot-starter-parent來配置你的項目,查看下面列出的parent:
<!-- Inherit defaults from Spring Boot -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
</parent>
你應(yīng)該只在這個依賴中聲明Spring Boot的版本。如果你導(dǎo)入其它的啟動器,你可以安全的省略版本號
使用該設(shè)置,您還可以通過覆蓋自己項目中的屬性來覆蓋各個依賴項。 例如,要升級到另一個Spring Data發(fā)布系列,您可以將以下內(nèi)容添加到pom.xml中:
<properties>
<spring-data-releasetrain.version>Fowler-SR2</spring-data-releasetrain.version>
</properties>
查看 spring-boot-dependencies pom文件列出的屬性
不使用父POM來使用Spring Boot
并不是每個人都喜歡繼承spring-boot-starter-parent的POM文件。您可能需要使用自己的公司標(biāo)準(zhǔn)parent,或者可能希望顯示聲明所有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>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
上面的示例配置沒有允許您通過使用屬性來覆蓋各個依賴項。為了獲得相同的結(jié)果,需要在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>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>2.2.6.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
在生疏示例總,我們指定了一個BOM,但是任何依賴項類型都可以以相同方式覆蓋
使用Spring Boot Maven Plugin
Spring Boot包含了一個將項目打包成可執(zhí)行jar的Maven插件,若果要使用它就將這個插件像下面的示例一樣添加到你的<plugins>中:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
如果你使用Spring Boot starter的父Pom,您只需要添加這個插件,并不需要任何配置除非你想改變在父Pom中定義的設(shè)置
3.1.3 Gradle
要將Spring Boot和Gradle一起使用,請參考Spring Boot的Gradle插件文檔:
3.1.4 Ant
可以使用Apache Ant + Ivy構(gòu)建Spring Boot項目。 spring-boot-antlib“ AntLib”模塊也可用于幫助Ant創(chuàng)建可執(zhí)行的jar。
要聲明依賴關(guān)系,典型的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.2.6.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模塊,請參閱不使用spring-boot-antlib“如何”而從Ant構(gòu)建可執(zhí)行檔案。
3.1.5 Starters
Starters是一組方便的依賴項描述符,您可以在應(yīng)用程序中包括它們。 您可以一站式購買所需的所有Spring和相關(guān)技術(shù),而不必搜尋示例代碼和依賴描述符的復(fù)制粘貼負(fù)載。 例如,如果要開始使用Spring和JPA進行數(shù)據(jù)庫訪問,請在項目中包括spring-boot-starter-data-jpa依賴項。
Starters包含許多啟動項目并快速運行所需的依賴項,并且具有一組受支持的受管傳遞性依賴項
名稱包含什么
所有官方Starters都遵循類似的命名方式。 spring-boot-starter-*,其中*是特定類型的應(yīng)用程序。 這種命名結(jié)構(gòu)旨在在您需要尋找入門者時提供幫助。 許多IDE中的Maven集成使您可以按名稱搜索依賴項。 例如,在安裝了適當(dāng)?shù)腅clipse或STS插件的情況下,您可以在POM編輯器中按ctrl-space并鍵入“ spring-boot-starter”以獲取完整列表。
Spring Boot在org.springframework.boot組下提供了以下應(yīng)用程序Starter:
Table 1. Spring Boot應(yīng)用程序Starter
| Name | Description | Pom |
|---|---|---|
| spring-boot-starter | 核心Starter,包含自動配置支持,日志和YAML | Pom |
| spring-boot-starter-activemq | 使用Apache ActiveMQ的JMS消息的Starter | Pom |
| spring-boot-starter-amqp | 使用Spring AMQP和Rabbit MQ的Starter | Pom |
| spring-boot-starter-aop | 使用Spring AOP和AspectJ進行面向方面編程的Starter | Pom |
| spring-boot-starter-artemis | 使用Apache Artemis的JMS消息傳遞Starter | Pom |
| spring-boot-starter-batch | 使用Spring Batch的Starter | Pom |
| spring-boot-starter-cache | 使用Spring Framework的緩存支持的Starter | Pom |
| spring-boot-starter-cloud-connectors | 使用Spring Cloud Connectors的Starter,可簡化與Cloud Foundry和Heroku等云平臺中服務(wù)的連接。不推薦使用Java CFEnv | Pom |
| spring-boot-starter-data-cassandra | 使用Cassandra分布式數(shù)據(jù)庫和Spring Data Cassandra Reactive的Starter | Pom |
| spring-boot-starter-data-couchbase | 使用Couchbase面向文檔的數(shù)據(jù)庫和Spring Data Couchbase的入門 | Pom |
| spring-boot-starter-data-elasticsearch | 使用Elasticsearch搜索和分析引擎以及Spring Data Elasticsearch的Starter | Pom |
| spring-boot-starter-data-jdbc | 使用Spring Data JDBC的Starter | Pom |
| spring-boot-starter-data-jpa | 將Spring Data JPA與Hibernate結(jié)合使用的Starter | Pom |
| spring-boot-starter-data-ldap | 使用Spring Data LDAP的Starter | Pom |
| spring-boot-starter-data-mongodb | 使用MongoDB面向文檔的數(shù)據(jù)庫和Spring Data MongoDB的Starter | Pom |
| spring-boot-starter-data-mongodb-reactive | 使用MongoDB面向文檔的數(shù)據(jù)庫和Spring Data MongoDB Reactive的Starter | Pom |
| spring-boot-starter-data-neo4j | 使用Neo4j圖形數(shù)據(jù)庫和Spring Data Neo4j的Starter | Pom |
| spring-boot-starter-data-redis | 使用Redis鍵值數(shù)據(jù)存儲與Spring Data Redis和Lettuce客戶端的Starter | Pom |
| spring-boot-starter-data-redis-reactive | 將Redis鍵值數(shù)據(jù)存儲與Spring Data Redis Reacting和Lettuce客戶端一起使用的Starter | Pom |
| spring-boot-starter-data-rest | 使用Spring Data REST通過REST公開Spring數(shù)據(jù)存儲庫的Starter | Pom |
| spring-boot-starter-data-solr | 將Apache Solr搜索平臺與Spring Data Solr結(jié)合使用的Starter | Pom |
| spring-boot-starter-freemarker | 使用FreeMarker視圖構(gòu)建MVC Web應(yīng)用程序的Starter | Pom |
| spring-boot-starter-groovy-templates | 使用Groovy模板視圖構(gòu)建MVC Web應(yīng)用程序的Starter | Pom |
| spring-boot-starter-hateoas | 使用Spring MVC和Spring HATEOAS構(gòu)建基于超媒體的RESTful Web應(yīng)用程序的Starter | Pom |
| spring-boot-starter-integration | 使用Spring Integration的Starter | Pom |
| spring-boot-starter-jdbc | 結(jié)合使用JDBC和HikariCP連接池的Starter | Pom |
| spring-boot-starter-jersey | 使用JAX-RS和Jersey構(gòu)建RESTful Web應(yīng)用程序的Starter,的替代品spring-boot-starter-web | Pom |
| spring-boot-starter-jooq | 使用jOOQ訪問SQL數(shù)據(jù)庫的Starter,spring-boot-starter-data-jpa或spring-boot-starter-jdbc的替代品 | Pom |
| spring-boot-starter-json | 讀寫JSON的Starter | Pom |
| spring-boot-starter-jta-atomikos | 使用Atomikos的JTA事務(wù)的Starter | Pom |
| spring-boot-starter-jta-bitronix | 使用Bitronix的JTA事務(wù)的Starter | Pom |
| spring-boot-starter-mail | 使用Java Mail和Spring Framework的電子郵件發(fā)送支持的Starter | Pom |
| spring-boot-starter-mustache | 使用Mustache視圖構(gòu)建Web應(yīng)用程序的Starter | Pom |
| spring-boot-starter-oauth2-client | 使用Spring Security的OAuth2 / OpenID Connect客戶端功能的Starter | Pom |
| spring-boot-starter-oauth2-resource-server | 使用Spring Security的OAuth2資源服務(wù)器功能的Starter | Pom |
| spring-boot-starter-quartz | 使用Quartz Scheduler的Starter | Pom |
| spring-boot-starter-rsocket | 用于構(gòu)建RSocket客戶端和服務(wù)器的Starter | Pom |
| spring-boot-starter-security | 使用Spring Security的Starter | Pom |
| spring-boot-starter-test | 用于使用包括JUnit,Hamcrest和Mockito在內(nèi)的庫測試Spring Boot應(yīng)用程序的Starter | Pom |
| spring-boot-starter-thymeleaf | 使用Thymeleaf視圖構(gòu)建MVC Web應(yīng)用程序的Starter | Pom |
| spring-boot-starter-validation | 通過Hibernate Validator使用Java Bean驗證的Starter | Pom |
| spring-boot-starter-web | 使用Spring MVC構(gòu)建Web(包括RESTful)應(yīng)用程序的Starter。使用Tomcat作為默認(rèn)的嵌入式容器 | Pom |
| spring-boot-starter-web-services | 使用Spring Web Services的Starter | Pom |
| spring-boot-starter-webflux | 使用Spring Framework的Reactive Web支持構(gòu)建WebFlux應(yīng)用程序的Starter | Pom |
| spring-boot-starter-websocket | 使用Spring Framework的WebSocket支持構(gòu)建WebSocket應(yīng)用程序的Starter | Pom |
除了應(yīng)用程序啟動程序,以下啟動程序可用于添加生產(chǎn)就緒功能:
Table 2. Spring Boot生產(chǎn)Starter
| Name | Description | Pom |
|---|---|---|
| spring-boot-starter-actuator | 使用Spring Boot的Actuator的Starter,它提供了生產(chǎn)就緒功能,可幫助您監(jiān)視和管理應(yīng)用程序 | Pom |
最后,Spring Boot還包括以下啟動程序,如果您想排除或交換特定的技術(shù)方面,可以使用這些啟動程序:
Table 3. Spring Boot技術(shù)入門
| Name | Description | Pom |
|---|---|---|
| spring-boot-starter-jetty | 使用Jetty作為嵌入式servlet容器的Starter,spring-boot-starter-tomcat的替代品 | Pom |
| spring-boot-starter-log4j2 | 使用Log4j2進行日志記錄的Starter,spring-boot-starter-logging的替代品 | Pom |
| spring-boot-starter-logging | 使用Logback進行日志記錄的Starter,默認(rèn)日志Starter | Pom |
| spring-boot-starter-reactor-netty | 使用Reactor Netty作為嵌入式反應(yīng)式HTTP服務(wù)器的Starter | Pom |
| spring-boot-starter-tomcat | 用于將Tomcat用作嵌入式Servlet容器Starter,spring-boot-starter-web默認(rèn)使用的servlet容器Starter | Pom |
| spring-boot-starter-undertow | 使用Undertow作為嵌入式servlet容器的Starter,spring-boot-starter-tomcat的替代品 | Pom |
有關(guān)社區(qū)貢獻的其他入門者的列表,請參閱GitHub中spring-boot-starters模塊中的README文件
3.2 結(jié)構(gòu)化代碼
Spring Boot不需要任何特定的代碼布局即可工作。 但是,有一些最佳做法可以幫助您
3.2.1 使用默認(rèn)包
當(dāng)類不包含程序包聲明時,將其視為在“默認(rèn)程序包”中。 通常不建議使用“默認(rèn)程序包”,應(yīng)避免使用。 對于使用@ ComponentScan,@ ConfigurationPropertiesScan,@ EntityScan或@SpringBootApplication注解的Spring Boot應(yīng)用程序,這可能會導(dǎo)致特定的問題,因為每個jar中的每個類都會被讀取。
我們建議您遵循Java建議的程序包命名約定,并使用反向域名(例如com.example.project)。
3.2.2 放置應(yīng)用程序主類
我們通常推薦您將應(yīng)用程序主類放置在其它類下根包中。@SpringBootApplicaton注解經(jīng)常放在你的主類中,它隱式的定義了某些條目的基礎(chǔ)搜索路徑。例如,你正在開發(fā)一個JPA應(yīng)用,@SpringBootApplication注解的類的包被用來搜索@Entity,使用根包也可以將組件掃描應(yīng)用于你的項目。
如果你不想使用@SpringBootApplication注解,@EnableAutoConfiguration和@ComponentScan也定義了那些功能,所以你可以使用它們作為替代。
下面列出了一個經(jīng)典的布局
com
+- example
+- myapplication
+- Application.java
|
+- customer
| +- Customer.java
| +- CustomerController.java
| +- CustomerService.java
| +- CustomerRepository.java
|
+- order
+- Order.java
+- OrderController.java
+- OrderService.java
+- OrderRepository.java
Applicaton.java文件會聲明main方法,以及基本的@SpringBootApplication注解,如下所示:
package com.example.myappmlication;
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);
}
}
3.3 配置類
Spring Boot支持基于Java的配置,盡管可以將SpringApplicaton和XML源一起使用,我們通常建議您的主要代碼為單個@Confuguration類。通常,定義Main方法的類是首選的@Configuration。
網(wǎng)上有很多使用XML配置的Spring示例,如果可能,盡量使用基于Java的配置。搜索@Enable*注解會是一個很好的開始。
3.3.1 導(dǎo)入額外的配置類
你不需要在每個類上加@Configuration注解,@Import注解可以用來加載其他的配置類。你也可以使用@ComponentScan注解來掃描所有的Spring組件,包括@Configuration注解的類。
3.3.2 導(dǎo)入XML配置
如果你一定要是使用基于XML的配置,我們建議您依然從@Configuration類開始,然后使用@ImportResource注解來加載XML配置文件。
3.4 自動配置
Spring Boot的自動配置會嘗試根據(jù)你導(dǎo)入的依賴來自動配置你的應(yīng)用。例如,如果HSQLDB在你的類路徑中,但你并沒有手動配置任何數(shù)據(jù)庫連接Bean,那么Spring Boot會自動配置一個內(nèi)存型數(shù)據(jù)庫。
您需要通過向@Configuration類之一添加@EnableAutoConfiguration或@SpringBootApplication注釋來選擇加入自動配置。
你只需要加入@EnableAutoConfiguration或@SpringBootApplication之一,我們通常推薦你添加其中一個到你的一個配置類中。
3.4.1 逐漸取代自動配置
自動配置是非侵入性的,在任何時候,你可以自定義你的配置來代替自動配置的特定部分。例如,當(dāng)你添加你的數(shù)據(jù)庫連接Bean,那么默認(rèn)的內(nèi)嵌數(shù)據(jù)庫會被取代。
如果你想知道正在應(yīng)用的自動配置是什么,為什么這么配置,那就以debug模式啟動你的應(yīng)用,這樣做可以啟用調(diào)試日志,以選擇核心記錄器,并將條件報告記錄到控制臺。
3.4.2 關(guān)閉特定的配置類
如果你發(fā)現(xiàn)一個正在被使用的配置類不是你想要的,你可以使用@SpringBootApplication注解的exclude屬性來關(guān)閉它,正如下所示:
import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})
public class MyApplication {
}
如果這個類不在類路徑中,你可用使用該注解的excludeName屬性和使用類的全路徑限定名來作為替代。如果你比起@SpringBootApplication更傾向于使用@EnableAutoConfiguration注解,exclude和excludeName也是可以使用的。最后,您還可以使用spring.autoconfigure.exclude屬性控制要排除的自動配置類的列表。
您可以在注解級別和使用屬性來定義排除項。
即使自動配置類是公共的,該類的唯一方面也被認(rèn)為是公共API,該類的名稱可以用于禁用自動配置。 這些類的實際內(nèi)容(例如嵌套配置類或Bean方法)僅供內(nèi)部使用,我們不建議直接使用它們。
3.5 SpringBean和依賴注入
你可以自由的選擇使用標(biāo)準(zhǔn)Spring Framework技術(shù)來定義你的Bean和依賴注入。為簡單起見,我們發(fā)現(xiàn)使用@ComponentScan(掃描你的Bean)和@Autowired(用來構(gòu)造器注入)效果很好。
如果你按照上面的建議來組織你的代碼(把你的應(yīng)用啟動類放在根包),你可以添加@ComponentScan而不使用任何參數(shù),你的所有Spring組件(@Component,@Repository,@Service,@Controller等等)將會被自動注冊為Bean。
以下示例顯示了一個@Service Bean,它使用構(gòu)造函數(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 {
private final RiskAssessor riskAssessor;
@Autowired
public DatabaseAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}
// ...
}
如果bean具有一個構(gòu)造函數(shù),則可以省略@Autowired,如以下示例所示:
@Service
public class DatabaseAccountService implements AccountService {
private final RiskAssessor riskAssessor;
public DatabaseAccountService(RiskAssessor riskAssessor) {
this.riskAssessor = riskAssessor;
}
// ...
}
請注意,使用構(gòu)造函數(shù)注入使riskAssessor字段被標(biāo)記為final,表明它隨后無法更改。
3.6 使用@SpringBootApplication注解
許多Spring Boot開發(fā)人員喜歡他們的應(yīng)用使用自動配置,組件掃描并可以添加額外的配置到應(yīng)用啟動類上,單個的@SpringBootApplication注解可以開啟下面三個功能:
- @EnableAutoConfiguration 開啟Spring Boot的自動配置機制
- @ComponentScan:在應(yīng)用程序所在的軟件包上啟用@Component掃描(請參閱最佳實踐)
- @Configuration 允許注入額外的Bean到上下文中或?qū)腩~外的配置類。
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的屬性。
這些功能都不是強制性的,您可以選擇用它啟用的任何功能替換此單個注釋。 例如,您可能不想在應(yīng)用程序中使用組件掃描或配置屬性掃描:
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(proxyBeanMethods = false) @EnableAutoConfiguration @Import({ MyConfig.class, MyAnotherConfig.class }) public class Application { public static void main(String[] args) { SpringApplication.run(Application.class, args); } }在此示例中,除了不會自動檢測到@Component注釋的類和@ConfigurationProperties注釋的類并且顯式導(dǎo)入用戶定義的Bean外,Application就像其他任何Spring Boot應(yīng)用程序一樣(請參閱@Import)。
3.7 運行你的應(yīng)用
將應(yīng)用打包成為Jar包并使用內(nèi)嵌HTTP服務(wù)器的最大好處是你可以在任何時候運行你的應(yīng)用。調(diào)試Spring Boot應(yīng)用也變得非常容易,你不需要任何特殊的IDE插件或擴展。
3.7.1 在IDE中運行你的應(yīng)用
你可以像一個簡單的Java應(yīng)用一樣在IDE中運行Spring Boo,但是你首先需要導(dǎo)入你的項目,導(dǎo)入過程根據(jù)你的IDE和構(gòu)建系統(tǒng)有所區(qū)別。大多數(shù)IDE可以直接導(dǎo)入Maven工程,例如,Eclipse用戶可以從File菜單中選擇Import->Existing Maven Projects導(dǎo)入。
如果你不能將應(yīng)用直接導(dǎo)入你的IDE,你可能需要用構(gòu)建插件來生成IDE元數(shù)據(jù)。Maven包含了Eclipse和IDEA的插件,Gradle也同樣為一些IDE提供了插件。
如果突然將一個Web應(yīng)用運行兩次,會看到一個“Port is already in use”的錯誤。STS用戶可以使用ReLaunch按鈕而不是Run來確保存在的實例被關(guān)閉。
3.7.2 運行打包后的程序
如果你使用Spring Boot的Maven或Gradle插件來生成可執(zhí)行jar,你可以像下面的示例一樣,使用java -jar來運行你的應(yīng)用
$ java -jar target/myapplication-0.0.1-SNAPSHOT.jar
可以在運行一個打包的應(yīng)用的同時開啟遠程調(diào)試,這樣做可以將一個debugger和你的應(yīng)用連接起來,像下面的示例一樣:
$ java -jar -Xdebug -Xrunjdwp:server=y,transport=dt_socket,address=8000,suspend=n \
-jar target/myapplication-0.0.1-SNAPSHOT.jar
3.7.3 使用Maven插件
Spring Boot的Maven插件包含了一個運行的目標(biāo),可以來快速的編譯運行你的應(yīng)用。應(yīng)用可以像在IDE中一樣以一種暴露的方式運行。下面的示例展示了一個用經(jīng)典的Maven命令來運行應(yīng)用:
$ mvn spring-boot:run
您可能還想使用MAVEN_OPTS操作系統(tǒng)環(huán)境變量,如以下示例所示:
$ export MAVEN_OPTS=-Xmx1024m
3.7.4 使用Gradle插件
Spring Boot Gradle插件還包含一個bootRun任務(wù),該任務(wù)可用于以暴露的方式運行您的應(yīng)用程序。 每當(dāng)您應(yīng)用org.springframework.boot和java插件時,都會添加bootRun任務(wù),并在以下示例中顯示:
$ gradle bootRun
您可能還想使用JAVA_OPTS操作系統(tǒng)環(huán)境變量,如以下示例所示:
$ export JAVA_OPTS=-Xmx1024m
3.7.5 熱交換
因為Spring Boot應(yīng)用是指普通的Java應(yīng)用,JVM熱交換應(yīng)該可以立即使用。JVM熱交換在一定程度上受到它可以替換的字節(jié)碼的限制,對于更完善的解決方案,可以使用JRebel。
spring-boot-devtools也包含了應(yīng)用快速啟動的支持,有關(guān)詳細(xì)信息,請參見本章稍后的“devtools”部分和熱交換“操作方法”。
3.8 DevTools
Spring Boot包括一組額外的工具,這些工具可以使應(yīng)用程序開發(fā)體驗更加愉快。spring-boot-devtools模塊可以添加到任何的工程中來提供額外的開發(fā)時特性。要包括devtools支持,請將模塊依賴項添加到您的構(gòu)建中,如以下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")
}
開發(fā)人員工具會在運行完全打包應(yīng)用的時候被自動關(guān)閉。如果您的應(yīng)用程序是從java -jar啟動的,或者是從特殊的類加載器啟動的,則將其視為“生產(chǎn)應(yīng)用程序”。 如果這不適用于您(即,如果您從容器中運行應(yīng)用程序),請考慮排除devtools或設(shè)置-Dspring.devtools.restart.enabled = false系統(tǒng)屬性。
在Maven中將依賴項標(biāo)記為可選,或在Gradle中使用自定義developmentOnly配置(如上所示)是一種最佳做法,可防止將devtools過渡地應(yīng)用到使用項目的其他模塊。
重新打包的存檔默認(rèn)情況下不包含devtools。 如果要使用某個遠程devtools功能,則需要禁用excludeDevtools構(gòu)建屬性以包括它。 Maven和Gradle插件均支持該屬性。
3.8.1 默認(rèn)屬性
Spring Boot支持的一些庫使用緩存來提高性能。例如,模板引擎 template engines緩存已編譯的模板,以避免重復(fù)解析模板文件。 而且,Spring MVC可以在提供靜態(tài)資源時向響應(yīng)添加HTTP緩存標(biāo)頭。
盡管緩存在生產(chǎn)中非常有益,但在開發(fā)過程中可能適得其反,從而使您無法看到自己剛剛在應(yīng)用程序中所做的更改。 因此,默認(rèn)情況下,spring-boot-devtools禁用緩存選項。
緩存選項通常由application.properties文件中的設(shè)置配置。 例如,Thymeleaf提供spring.thymeleaf.cache屬性。 spring-boot-devtools模塊不需要自動設(shè)置這些屬性,而是自動應(yīng)用合理的開發(fā)時配置。
因為在開發(fā)Spring MVC和Spring WebFlux應(yīng)用程序時需要有關(guān)Web請求的更多信息,所以devtools將為Web日志記錄組啟用DEBUG日志記錄。 這將為您提供有關(guān)傳入請求,處理程序正在處理的信息,響應(yīng)結(jié)果等信息。如果您希望記錄所有請求詳細(xì)信息(包括潛在的敏感信息),則可以打開spring.http.log-request- details配置屬性。
如果你不想使用默認(rèn)屬性,可以在application.properties文件中設(shè)置spring.devtool.add-properties為false
有關(guān)devtools應(yīng)用的屬性的完整列表,請參見DevToolsPropertyDefaultsPostProcessor
3.8.2 啟動重啟
使用spring-boot-devtools的應(yīng)用會在類路徑下的文件改變時自動重啟,在IDE中工作時,這可能是一個有用的功能,因為它為代碼更改提供了非??焖俚姆答佈h(huán)。 默認(rèn)情況下,將監(jiān)視類路徑上指向文件夾的任何條目的更改。 請注意,某些資源(例如靜態(tài)資產(chǎn)和視圖模板)不需要重新啟動應(yīng)用程序。
觸發(fā)重啟
當(dāng)DevTools監(jiān)視類路徑資源時,觸發(fā)重啟的唯一方法是更新類路徑。 導(dǎo)致類路徑更新的方式取決于您使用的IDE。 在Eclipse中,保存修改后的文件將導(dǎo)致類路徑被更新并觸發(fā)重新啟動。 在IntelliJ IDEA中,構(gòu)建項目(Build +→+ Build Project)具有相同的效果。
只要啟用了fork,您還可以使用受支持的構(gòu)建插件(Maven和Gradle)來啟動應(yīng)用程序,因為DevTools需要隔離的應(yīng)用程序類加載器才能正常運行。 默認(rèn)情況下,Gradle和Maven插件會fork應(yīng)用程序進程。
與LiveReload一起使用時,自動重啟非常有效。 有關(guān)詳細(xì)信息,請參見LiveReload部分。 如果使用JRebel,則禁用自動重新啟動,而支持動態(tài)類重新加載。 其他devtools功能(例如LiveReload和屬性替代)仍可以使用。
DevTools依靠應(yīng)用程序上下文的關(guān)閉掛鉤在重新啟動期間將其關(guān)閉。 如果您禁用了關(guān)閉掛鉤(SpringApplication.setRegisterShutdownHook(false)),它將無法正常工作。
在確定類路徑上的條目是否應(yīng)在更改后觸發(fā)重新啟動時,DevTools會自動忽略名為spring-boot,spring-boot-devtools,spring-boot-autoconfigure,spring-boot-actuator和spring-boot-starter的項目。
DevTools需要自定義ApplicationContext使用的ResourceLoader。 如果您的應(yīng)用程序已經(jīng)提供了,它將被包裝。 不支持在ApplicationContext上直接重寫getResource方法。
重啟VS重加載重啟技術(shù)是通過Spring Boot使用兩個類加載器來實現(xiàn),不變的類(例如那些第三方Jar包中的)被加載到一個基本類加載器,你正在開發(fā)的類使用一個restart類加載器,當(dāng)應(yīng)用重啟時,restart類加載器被丟掉并新建一個實例,這種方式意味著比傳統(tǒng)的冷啟動更快,因為基本類加載器一直可用并已填充
如果發(fā)現(xiàn)重新啟動對于您的應(yīng)用程序而言不夠快,或者遇到類加載問題,則可以考慮從ZeroTurnaround重新加載技術(shù),例如JRebel。 這些方法通過在加載類時重寫類來使它們更適合于重新加載。
記錄條件評估中的更改
默認(rèn)每次應(yīng)用重啟時,記錄條件評估增量的報告。該報告顯示了您進行更改(例如添加或刪除Bean以及設(shè)置配置屬性)時對應(yīng)用程序自動配置的更改。
要禁用報告的日志記錄,請設(shè)置以下屬性:
spring.devtools.restart.log-condition-evaluation-delta=false
排除資源
某些資源在更改時不一定需要觸發(fā)重新啟動。 例如,Thymeleaf模板可以就地編輯。 默認(rèn)情況下,更改/ META-INF/mave,/META-INF/resources,/resources,/static,/public或/templates中的資源不會觸發(fā)重新啟動,但會觸發(fā)實時重新加載。 如果要自定義這些排除項,則可以使用spring.devtools.restart.exclude屬性。 例如,要僅排除/ static和/ public,可以設(shè)置以下屬性:
spring.devtools.restart.exclude=static/**,public/**
如果你想保持默認(rèn)的配置并增加一些額外的排除項,請使用spring.devtools.restart.addtional-exclude屬性作為替代
監(jiān)測額外路徑
當(dāng)您對不在類路徑上的文件進行更改時,您可能希望重新啟動或重新加載應(yīng)用程序。 為此,請使用spring.devtools.restart.additional-paths屬性配置其他路徑以監(jiān)視更改。 您可以使用前面所述的spring.devtools.restart.exclude屬性來控制其他路徑下的更改是觸發(fā)完全重啟還是動態(tài)重新加載。
關(guān)閉重啟
如果你不想使用重啟功能,你可以設(shè)置spring.devtool.restart.enabled屬性來關(guān)閉它。在大多數(shù)情況下,您可以在application.properties中設(shè)置此屬性(這樣做仍會初始化restart類加載器,但它不會監(jiān)視文件更改)。
如果您需要完全禁用重啟支持(例如,因為它不適用于特定的庫),則需要在調(diào)用SpringApplication.run(...)之前將spring.devtools.restart.enabled系統(tǒng)屬性設(shè)置為false,例如 如以下示例所示:
public static void main(String[] args) {
System.setProperty("spring.devtools.restart.enabled", "false");
SpringApplication.run(MyApp.class, args);
}
使用觸發(fā)文件
如果使用持續(xù)編譯更改文件的IDE,則可能更喜歡僅在特定時間觸發(fā)重新啟動。 為此,您可以使用“觸發(fā)文件”,這是一個特殊文件,當(dāng)您要實際觸發(fā)重新啟動檢查時必須對其進行修改。
對文件的任何更新都會觸發(fā)檢查,但是只有在Devtools檢測到有事情要做的情況下,重啟才會真正發(fā)生。
要使用觸發(fā)文件,請將spring.devtools.restart.trigger-file屬性設(shè)置為觸發(fā)文件的名稱(不包括任何路徑)。 觸發(fā)器文件必須出現(xiàn)在類路徑上的某個位置。
例如,如果您的項目具有以下結(jié)構(gòu):
src
+- main
+- resources
+- .reloadtrigger
那么你的trigger-file屬性會是這樣的:
spring.devtools.restart.trigger-file=.reloadtrigger
現(xiàn)在重啟只會在src/main/resources/.reloadtrigger文件更新是發(fā)生
您可能希望將spring.devtools.restart.trigger-file設(shè)置為全局設(shè)置,以便所有項目的行為均相同。
某些IDE具有使您不必手動更新觸發(fā)器文件的功能。Spring Tools for Eclipse
和 IntelliJ IDEA (Ultimate Edition)都具有這種支持。 使用Spring Tools,您可以從控制臺視圖使用“重新加載”按鈕(只要您的觸發(fā)文件名為.reloadtrigger)。 對于IntelliJ,您可以按照其文檔中的說明進行操作。
定制Restart類加載器
如前面的“重新啟動與重新加載”部分所述,重新啟動功能是通過使用兩個類加載器實現(xiàn)的。 對于大多數(shù)應(yīng)用程序,此方法效果很好。 但是,有時可能會導(dǎo)致類加載問題。
默認(rèn)情況下,IDE中任何打開的項目都使用“重新啟動”類加載器加載,而任何常規(guī).jar文件都使用“基本”類加載器加載。 如果您在多模塊項目上工作,并且并非每個模塊都導(dǎo)入到IDE中,則可能需要自定義內(nèi)容。 為此,您可以創(chuàng)建一個META-INF / spring-devtools.properties文件。
spring-devtools.properties文件可以包含帶有restart.exclude和restart.include前綴的屬性。 include元素是應(yīng)上拉到“重新啟動”類加載器中的項目,而exclude元素是應(yīng)下推到“基本”類加載器中的項目。 該屬性的值是一個應(yīng)用于類路徑的正則表達式模式,如以下示例所示:
restart.exclude.companycommonlibs=/mycorp-common-[\\w\\d-\.]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w\\d-\.]+\.jar
所有屬性鍵都必須是唯一的。 只要屬性以restart.include開頭, 或restart.exclude開頭,都會被考慮在內(nèi)
類路徑中的所有META-INF / spring-devtools.properties將被加載。 您可以將文件打包到項目內(nèi)部或項目使用的庫中。
已知局限性
重新啟動功能不適用于使用標(biāo)準(zhǔn)ObjectInputStream反序列化的對象。 如果您需要反序列化數(shù)據(jù),則可能需要將Spring的ConfigurableObjectInputStream與Thread.currentThread().getContextClassLoader()結(jié)合使用。
如果您不想在應(yīng)用程序運行時啟動LiveReload服務(wù),則可以將spring.devtools.livereload.enabled屬性設(shè)置為false。
一次只能運行一個LiveReload服務(wù)。 在啟動應(yīng)用程序之前,請確保沒有其他LiveReload服務(wù)正在運行。 如果從IDE啟動多個應(yīng)用程序,則只有第一個具有LiveReload支持。
3.8.4 全局設(shè)置
您可以通過將以下任何文件添加到$HOME/.config / spring-boot文件夾來配置全局devtools設(shè)置:
- spring-boot-devtools.properties
- spring-boot-devtools.yaml
- spring-boot-devtools.yml
添加到這些文件的任何屬性都將應(yīng)用于使用devtools的計算機上的所有Spring Boot應(yīng)用程序。 例如,要將重新啟動配置為始終使用觸發(fā)文件,應(yīng)添加以下屬性:
~/.config/spring-boot/spring-boot-devtools.properties
spring.devtools.restart.trigger-file=.reloadtrigger
如果在$HOME/.config/spring-boot中找不到devtools配置文件,則在$HOME文件夾的根目錄中搜索是否存在.spring-boot-devtools.properties文件。 這使您可以與不支持$HOME/.config/spring-boot位置的較舊版本的Spring Boot上的應(yīng)用程序共享devtools全局配置。
在上述文件中激活的配置文件不會影響特定配置文件的加載。
3.8.5 遠程應(yīng)用
Spring Boot開發(fā)人員工具不僅限于本地開發(fā)。 遠程運行應(yīng)用程序時,您還可以使用多種功能。 選擇啟用遠程支持,可能會帶來安全風(fēng)險。 僅當(dāng)在受信任的網(wǎng)絡(luò)上運行或使用SSL保護時,才應(yīng)啟用它。 如果這兩個選項都不可用,則不應(yīng)使用DevTools的遠程支持。 您永遠不要在生產(chǎn)部署上啟用支持。
要啟用它,您需要確保重新打包的檔案中包含devtools,如以下清單所示:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludeDevtools>false</excludeDevtools>
</configuration>
</plugin>
</plugins>
</build>
然后,您需要設(shè)置spring.devtools.remote.secret屬性。 像任何重要的密碼或機密一樣,該值應(yīng)唯一且強壯,以免被猜測或強行使用。
遠程devtools支持分為兩個部分:接受連接的服務(wù)器端端點和在IDE中運行的客戶端應(yīng)用程序。 設(shè)置spring.devtools.remote.secret屬性后,將自動啟用服務(wù)器組件。 客戶端組件必須手動啟動。
運行遠程客戶端應(yīng)用
遠程客戶端應(yīng)用程序旨在在您的IDE中運行, 您需要使用與您連接到的遠程項目相同的類路徑來運行org.springframework.boot.devtools.RemoteSpringApplication。 該應(yīng)用程序的唯一必需參數(shù)是它連接到的遠程URL。
例如,如果您使用的是Eclipse或STS,并且有一個名為my-app的項目已部署到Cloud Foundry,則可以執(zhí)行以下操作:
- 從Run菜單中選擇Run Configuration
- 創(chuàng)建一個新的Java應(yīng)用啟動配置
- 選擇my-app項目
- 使用org.springframework.boot.devtools.RemodeSpringApplication作為啟動類
- 將https://myapp.cfapps.io(或你的URL)添加到程序參數(shù)中
正在運行的遠程客戶端可能類似于以下清單:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \
\\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) )
' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / /
=========|_|==============|___/===================================/_/_/_/
:: Spring Boot Remote :: 2.2.6.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-project/spring-boot-devtools/target/classes started by pwebb in /Users/pwebb/projects/spring-boot/code)
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)
因為遠程客戶端使用與真實應(yīng)用程序相同的類路徑,所以它可以直接讀取應(yīng)用程序?qū)傩浴?這就是讀取spring.devtools.remote.secret屬性并將其傳遞給服務(wù)器進行身份驗證的方式。
始終建議使用https://作為連接協(xié)議,以便對通信進行加密并且不能截獲密碼。
如果需要使用代理來訪問遠程應(yīng)用程序,請配置spring.devtools.remote.proxy.host和spring.devtools.remote.proxy.port屬性
遠程更新
遠程客戶端以與本地重新啟動相同的方式監(jiān)視應(yīng)用程序類路徑中的更改。 任何更新的資源都會推送到遠程應(yīng)用程序,并且(如果需要)會觸發(fā)重新啟動。 如果您迭代使用本地沒有的云服務(wù)的功能,這將很有幫助。 通常,遠程更新和重新啟動比完整的重建和部署周期要快得多。
僅在遠程客戶端正在運行時監(jiān)視文件。 如果在啟動遠程客戶端之前更改文件,則不會將其推送到遠程服務(wù)器。
配置文件系統(tǒng)觀察器
FileSystemWatcher的工作方式是按一定時間間隔輪詢類更改,然后等待預(yù)定義的靜默期以確保沒有更多更改。 然后將更改上傳到遠程應(yīng)用程序。 在較慢的開發(fā)環(huán)境中,可能會發(fā)生靜默期不夠的情況,并且類中的更改可能會分為幾批。 第一批類更改上傳后,服務(wù)器將重新啟動。 由于服務(wù)器正在重新啟動,因此下一批不能發(fā)送到應(yīng)用程序。
這通常通過RemoteSpringApplication日志中的警告來證明,即有關(guān)上載某些類失敗的消息,然后進行重試。 但是,這也可能導(dǎo)致應(yīng)用程序代碼不一致,并且在上傳第一批更改后無法重新啟動。
如果您經(jīng)常觀察到此類問題,請嘗試將spring.devtools.restart.poll-interval和spring.devtools.restart.quiet-period參數(shù)增加到適合您的開發(fā)環(huán)境的值:
spring.devtools.restart.poll-interval=2s
spring.devtools.restart.quiet-period=1s
現(xiàn)在每2秒輪詢一次受監(jiān)視的classpath文件夾是否有更改,并保持1秒鐘的靜默時間以確保沒有其他類更改。
3.9 打包您的生產(chǎn)應(yīng)用
可執(zhí)行jar可以用于生產(chǎn)部署。 由于它們是獨立的,因此它們也非常適合基于云的部署。
對于其他“生產(chǎn)準(zhǔn)備就緒”功能,例如運行狀況,審核和度量REST或JMX端點,請考慮添加spring-boot-actuator。 有關(guān)詳細(xì)信息,請參見Spring Boot Actuator:生產(chǎn)就緒功能。
3.10 接下來閱讀什么
現(xiàn)在,您應(yīng)該了解如何使用Spring Boot以及應(yīng)遵循的一些最佳實踐。 現(xiàn)在,您可以繼續(xù)深入了解特定的Spring Boot功能,或者可以跳過并閱讀有關(guān)Spring Boot的“生產(chǎn)就緒”方面的信息。