此篇翻譯的是Spring Boot官方指南 Part III. 使用 Spring Boot (Using Spring Boot)煤伟。查看前面章節(jié)移步這里
第三部分 使用Spring Boot
本節(jié)將更詳細介紹你應(yīng)該如何使用Spring Boot。 它涵蓋諸如構(gòu)建系統(tǒng)汁展,自動配置以及如何運行應(yīng)用程序等主題听怕。 我們也涵蓋了一些Spring Boot的最佳實踐。雖然Spring Boot沒有什么尤其特別的特點(它只是另一個你可以利用的庫)梧兼,這有一些建議當你按照它做時蹂窖,可以讓您的開發(fā)過程更容易一些。
如果您剛剛開始使用Spring Boot抡锈,那么在深入本節(jié)之前疾忍,您應(yīng)該大概閱讀入門指南。
13. 構(gòu)建系統(tǒng)
強烈建議您選擇一個支持依賴管理的構(gòu)建系統(tǒng)企孩,和一個可以消耗工件發(fā)布到“Maven Central”倉庫锭碳。 我們建議您選擇Maven或Gradle。 可以讓Spring Boot與其他構(gòu)建系統(tǒng)(例如Ant)配合使用勿璃,但是它們不會得到很好的支持。
13.1 依賴管理
每個版本的Spring Boot提供了一個它所支持的依賴列表推汽。 實際上补疑,您不需要為構(gòu)建配置中的任何這些依賴提供版本,因為Spring Boot正在為您進行管理歹撒。 當您升級Spring Boot本身時莲组,這些依賴也將以一致的方式進行升級。
| 如果您覺得有必要暖夭,您仍然可以指定一個版本并覆蓋Spring Boot建議锹杈。
策劃的列表包含可以使用Spring Boot的所有 spring 模塊以及第三方庫的精簡列表。 該列表可作為標準的物料清單(spring-boot-dependencies
)使用迈着,并且還額外提供了對Maven和Gradle的專用支持竭望。
| Spring Boot的每個版本與Spring Framework的一個基本版本相關(guān)聯(lián),因此我們強烈建議您不要自己指定其版本裕菠。
13.2 Maven
Maven用戶可以從 spring-boot-starter-parent-parent
項目中繼承咬清,以獲得合理的默認值。父項目提供以下功能:
- Java 1.6作為默認編譯器級別奴潘。
- 源代碼是UTF-8編碼旧烧。
-
依賴管理節(jié)點(Dependency Management section),允許您忽略常用依賴的
version
標簽画髓,繼承自spring-boot-dependencies
POM掘剪。 - 合理的資源過濾。
- 合理的插件配置(exec plugin, surefire, Git commit ID, shade)奈虾。
- 合理的
application.properties
和application.yml
資源過濾焰络,包括特定的profile文件(例如:application-foo.properties
和application-foo.yml
)
最后一點:由于默認的配置文件接受Spring樣式占位符($ {...}
)幻林,所以Maven過濾被更改為使用 @..@
占位符(您可以使用Maven的 resource.delimiter
屬性覆蓋它)痰滋。
13.2.1 繼承 starter parent
配置你的項目從 spring-boot-starter-parent
繼承,只需的設(shè)置 parent
(節(jié)點):
<!--從Spring Boot 繼承默認值 -->
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
</parent>
| 您只需要在此依賴項上指定Spring Boot版本號昂勉。 如果您導入額外的啟動器,則可以安全地省略版本號扫腺。
通過該設(shè)置岗照,您也可以在項目中通過屬性的優(yōu)勢覆蓋個別的依賴項,例如笆环,要升級到另一個Spring Data release train攒至,你需要添加以下內(nèi)容到你的 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
繼承躁劣,您可能需要使用你自己團隊擁有的標準 parent迫吐,或者你可能只是希望明確聲明你的Maven配置。
如果您不想使用 spring-boot-starter-parent
账忘,則仍然可以通過使用 scope=import
依賴來保持依賴管理(但不是插件管理)的好處:
<dependencyManagement>
<dependencies>
<dependency>
<!-- 從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>
該設(shè)置不允許您使用如上所述的屬性來覆蓋單個依賴志膀。要實現(xiàn)相同的結(jié)果,您需要在在項目的 dependencyManagement
中鳖擒,spring-boot-dependencies
條目之前添加一個條目溉浙。例如:要升級到另一個Spring Data release train,您需要將以下內(nèi)容添加到您的pom.xml中蒋荚。
<dependencyManagement>
<dependencies>
<!-- 覆蓋由Spring Boot提供的Spring Data release train -->
<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( Bills of Materials 物料清單),但是任何依賴類型都可以被這樣覆蓋期升。
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 包含一個可以將項目打包成可執(zhí)行的jar的Maven插件播赁。如果你想用它將插件放在你的 <plugins>
節(jié)點中:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
| 如果您使用Spring Boot啟動器父pom颂郎,則只需要添加插件,除非要更改父級中定義的設(shè)置行拢,否則不需要進行配置祖秒。
13.3 Gradle
Gradle 用戶可以直接在他們的 dependencies
部分引入"starters"。不像Maven舟奠,這沒有 "super parent" 去引入共享一些配置竭缝。
repositories {
jcenter()
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:1.5.2.RELEASE")
}
spring-boot-gradle-plugin
也是可用的,它提供了從源代碼創(chuàng)建可執(zhí)行jar并運行項目的任務(wù)沼瘫。 它還提供依賴管理抬纸,除其他功能外,還允許您省略由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創(chuàng)建Spring Boot項目耿戚。spring-boot-antlib
“AntLib”模塊也可用于幫助Ant創(chuàng)建可執(zhí)行jars
要聲明依賴湿故,一個典型的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>
| 如果你不想使用spring-boot-antlib
模塊阿趁。請參見第84.10節(jié), “不使用spring-boot-antlib從Ant創(chuàng)建一個可執(zhí)行的存檔” ”怎么做“
13.5 啟動器
啟動器是一組可以包含在應(yīng)用程序中的,方便的依賴關(guān)系描述符坛猪。 您可以獲得所需的所有Spring和相關(guān)技術(shù)的一站式服務(wù)脖阵,無需通過搜尋示例代碼和復制粘貼依賴描述符的加載。 例如墅茉,如果要開始使用Spring和JPA進行數(shù)據(jù)庫訪問命黔,那么只需在項目中包含 spring-boot-starter-data-jpa
依賴,即可準備好去做就斤。
啟動器包含許多您需要使項目啟動并快速運行的依賴悍募,并具有托管傳遞依賴一致的、受支持的集合洋机。
名字的含義
所有官方的啟動器都遵循類似的命名方式坠宴;
spring-boot-starter-*
,其中*
是一個特定類型的應(yīng)用绷旗。這個命名結(jié)構(gòu)旨在幫助你找到一個啟動器喜鼓。這個命名結(jié)構(gòu)旨在幫助你找到一個啟動器。 許多IDE中的Maven集成允許您按名稱搜索依賴項刁标。 例如颠通,安裝適當?shù)腅clipse或STS插件后,您可以簡單地在POM編輯器中點擊ctrl-space
膀懈,并輸入“spring-boot-starter”來獲取完整的列表。如創(chuàng)建自己的啟動器部分所述谨垃,第三方啟動程序不應(yīng)該以
Spring-boot
開頭启搂,因為它是為正式的Spring Boot工件保留的。acme
的第三方啟動器通常被命名為acme-spring-boot-starter
刘陶。
Spring Boot在 org.springframework.boot
組下提供了以下應(yīng)用程序啟動器:
表 13.1 Spring Boot 應(yīng)用啟動器
|名稱|描述|Pom|
|---|---|
|spring-boot-starter-thymeleaf
|使用Thymeleaf 視圖構(gòu)建MVC web應(yīng)用的啟動器|Pom|
|spring-boot-starter-data-couchbase
|使用Couchbase面向文檔的數(shù)據(jù)庫和Spring Data Couchbase|Pom|
|spring-boot-starter-artemis
|使用Apache Artemis實現(xiàn)JMS消息|Pom|
|spring-boot-starter-web-services
|用于Spring Web服務(wù)的啟動器|Pom|
|spring-boot-starter-mail
|用于Java郵件和Spring 框架的郵件發(fā)送支持的啟動器|Pom|
|spring-boot-starter-data-redis
|用于Redis 的key-value數(shù)據(jù)存儲同Spring Data Redis和Jedis 客戶端的啟動器|Pom|
|spring-boot-starter-web
|為構(gòu)建使用Spring MVC包括RESTful胳赌、web的應(yīng)用的啟動器,使用Tomcat作為默認的內(nèi)嵌容器|Pom|
|spring-boot-starter-data-gemfire
|用于GemFire分布式數(shù)據(jù)存儲和Spring Data GemFire的啟動器|Pom|
|spring-boot-starter-activemq
|使用Apache ActiveMQ實現(xiàn)JMS消息|Pom|
|spring-boot-starter-data-elasticsearch
|用于Elasticsearch搜索和分析引擎以及Spring Data Elasticsearch|Pom|
|spring-boot-starter-integration
|用于Spring集成|Pom|
|spring-boot-starter-test
|用于測試Spring Boot應(yīng)用包含的庫:JUnit匙隔、Hamcrest 疑苫、Mockito|Pom|
|spring-boot-starter-jdbc
|用于JDBC支持,使用Tomcat JDBC 連接池|Pom|
|spring-boot-starter-mobile
|使用Spring Mobile構(gòu)建web應(yīng)用的啟動器|Pom|
|spring-boot-starter-validation
|用于使用Hibernate Validator的Java Bean驗證啟動器|Pom|
|spring-boot-starter-hateoas
|使用Spring MVC和Spring HATEOAS構(gòu)建基于超媒體的RESTful web應(yīng)用的啟動器|Pom|
|spring-boot-starter-jersey
|使用 JAX-RS 和 Jersey構(gòu)建RESTful web應(yīng)用纷责, 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
|用于構(gòu)建WebSocket 應(yīng)用(使用spring 框架的WebSocket 支持)的啟動器|Pom|
|spring-boot-starter-aop
|用于基于Spring Aop和AspectJ的面向切面(aspect-oriented)編程的啟動器|Pom|
|spring-boot-starter-amqp
|使用Spring AMQP和Rabbit MQ|Pom|
|spring-boot-starter-data-cassandra
|使用Spring Cassandra 分布式數(shù)據(jù)庫和Spring Data Cassandra|Pom|
|spring-boot-starter-social-facebook
|使用Spring 社交的 facebook|Pom|
|spring-boot-starter-jta-atomikos
|用于基于Atomikos實現(xiàn)的JTA事務(wù)|Pom|
|spring-boot-starter-security
|用于Spring Security的啟動器|Pom|
|spring-boot-starter-mustache
|用于構(gòu)建Mustache 視圖實現(xiàn)的MVC web應(yīng)用|Pom|
|spring-boot-starter-data-jpa
|用于Hibernate實現(xiàn)的Spring Data JPA的啟動器|Pom|
|spring-boot-starter
|核心啟動器捍掺,包括自動配置支持、日志以及YAML|Pom|
|spring-boot-starter-groovy-templates
|使用Groovy 模版視圖實現(xiàn)構(gòu)建MVC web應(yīng)用|Pom|
|spring-boot-starter-freemarker
|使用FreeMarker 視圖構(gòu)建MVC web 應(yīng)用的啟動器|Pom|
|spring-boot-starter-batch
|對Spring Batch的支持|Pom|
|spring-boot-starter-social-linkedin
|用于為Spring Social LinkedIn的啟動器|Pom|
|spring-boot-starter-cache
|用于對Spring 框架的緩存支持的啟動器|Pom|
|spring-boot-starter-data-solr
|用于Spring Data Solr實現(xiàn)的 Apache Solr搜索平臺的啟動器|Pom|
|spring-boot-starter-data-mongodb
|用于MongoDB面向文檔數(shù)據(jù)庫和Spring Data MongoDB的啟動器|Pom|
|spring-boot-starter-jooq
|使用jOOQ SQL關(guān)系數(shù)據(jù)庫再膳,替代 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一樣的云平臺上服務(wù)連接。|Pom|
|spring-boot-starter-jta-bitronix
|使用Bitronix的JTA事務(wù)的啟動器|Pom|
|spring-boot-starter-social-twitter
|用于Spring Social Twitter的啟動器|Pom|
|spring-boot-starter-data-rest
|用于使用Spring Data REST暴露Spring Data 倉庫到REST之外|Pom|
除了應(yīng)用啟動器喂柒,以下啟動器可用于添加 production ready 功能:
表 13.2 Spring Boot 生產(chǎn)啟動器
名稱 | 描述 | Pom |
---|---|---|
spring-boot-starter-actuator | 使用Spring Boot Actuator提供生產(chǎn)就緒功能不瓶,去幫助您監(jiān)控和管理應(yīng)用的啟動器 | Pom |
spring-boot-starter-remote-shell | 使用CRaSH遠程shell通過SSH監(jiān)控和管理您的應(yīng)用程序禾嫉。 自1.5以來已棄用 | Pom |
最后,Spring Boot還包括一些啟動器蚊丐,如果要排除或交換特定的技術(shù)方面熙参,可以使用它們:
表13.3 Spring Boot 特定啟動器
名稱 | 描述 | Pom |
---|---|---|
spring-boot-starter-undertow |
使用Undertow 作為內(nèi)嵌的servlet容器,spring-boot-starter-tomcat 的替代方案 |
Pom |
spring-boot-starter-jetty |
使用jetty作為內(nèi)嵌的servlet容器麦备,spring-boot-starter-tomcat 的替代方案 |
Pom |
spring-boot-starter-logging |
日志使用Logback孽椰,默認的日志啟動器 | Pom |
spring-boot-starter-tomcat |
使用tomcat作為內(nèi)嵌的servlet容器。spring-boot-starter-web 使用的默認servlet容器啟動器 |
Pom |
spring-boot-starter-log4j2 |
使用Log4j2記錄日志泥兰。spring-boot-starter-logging 的替代方案 |
Pom |
| 額外的社區(qū)貢獻的啟動器的列表弄屡,請參閱GitHub上的spring-boot-startters模塊中的README文件。
14. 構(gòu)建你的代碼
Spring Boot 不要求任何特定代碼布局去工作鞋诗,然而膀捷,有一些最佳的做法可以幫助到你。
14.1 使用“默認的”包
當一個類不包含聲明的包時削彬,它被認為是在“默認包”中全庸。 通常不鼓勵使用“默認包”,應(yīng)該避免使用融痛。 對于使用@ComponentScan
壶笼,@EntityScan
或 @SpringBootApplication
注的Spring Boot應(yīng)用程序,可能會導致特殊的問題雁刷,因為會掃描每個jar下的每個類覆劈。
| 我們建議您遵循Java推薦的包命名約定,使用反向域名方式命名(例如:com.example.project
)
14.2 放置應(yīng)用的main類
我們通常建議您放置您應(yīng)用的main類在其他類之上的根目錄包下沛励。@EnableAutoConfiguration
注解經(jīng)常放在您的main上责语,它隱式地定義了某些項目的基本“搜索包”。例如:如果您正在編寫一個JPA應(yīng)用目派,則@EnableAutoConfiguration
注解的類所在的包將會被用來搜索 @Entity
實體坤候。
使用根目錄包還允許不需要指定 basePackage
屬性,來使用 @ComponentScan
注解企蹭。如果你的main類在根目錄包下白筹,你也可以使用 @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. 配置類
Sring Boot 提倡基于Java的配置。盡管可以使用XML源調(diào)用 SpringApplication.run()
螟凭,但我們通常建議您的主要源是 @Configuration
類虚青。通常,定義main方法的類是一個很好的候選人螺男,作為主要的 @Configuration
棒厘。
| 許多使用XML配置的Spring 配置示例已經(jīng)發(fā)布在Internet纵穿。如果可能的話要始終嘗試使用等效的基于Java的配置。搜索enable*
注解奢人,它可以是一個很好的起點谓媒。
15.1 導入其他配置類
您不需要將所有的 @Configuration
放在一個類中。@Import
注解可以用來導入其他配置類何乎【涔撸或者,你可以使用 @ComponentScan
注解自動提取所有的Spring 組件支救,包括 @Configuration
類抢野。
15.2 導入XML配置
如果您絕對必須使用基于XML的配置,我們建議您仍然從 @Configuration
類開始各墨。 然后指孤,您可以使用額外的 @ImportResource
注解來加載XML配置文件。
16. 自動配置
Spring Boot 自動配置(auto-configuration)嘗試基于您添加的jar依賴自動配置您的Spring應(yīng)用程序贬堵。例如恃轩,如果 HSQLDB
在您的類路徑上,并且您沒有手動配置任何數(shù)據(jù)庫連接bean黎做,那么我們將自動配置一個內(nèi)存數(shù)據(jù)庫叉跛。
您需要通過添加 @EnableAutoConfiguration
或 @SpringBootApplication
注解到一個你 @Configuration
的類來選擇加入自動配置。
| 您應(yīng)該只要添加一個@EnableAutoConfiguration
注解蒸殿。我們通常建議您將它添加到你的主要@Configuration
類上筷厘。
16.1 逐漸替換自動配置
自動配置是非侵入性的,你可以在任何時候開始定義自己的配置去替換自動配置的特定的部分宏所。例如敞掘,如果你添加自己的 DataSource
bean,則默認的內(nèi)嵌數(shù)據(jù)庫支持將會退回楣铁。
如果你想了解什么自動配置在當前存在應(yīng)用,以及為什么更扁,請使用 --debug
開關(guān)啟動你的應(yīng)用盖腕。這將啟用調(diào)試日志級別給核心日志記錄器一個選擇,并將記錄一個自動配置報告到控制臺浓镜。
16.2 禁用特定的自動配置
如果您發(fā)現(xiàn)你不想要的特定自動配置正在應(yīng)用溃列,可以使用 @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 {
}
如果該類不在類路徑上膛薛,則可以使用注解的 excludeName
屬性听隐,并指定完全限定名稱來代替。 最后哄啄,您還可以通過 spring.autoconfigure.exclude
屬性控制要排除的自動配置類列表雅任。
|在 注解級別和使用屬性您都可以定義排除項风范。
17. Spring Beans 和依賴注入
您可以自由使用任何標準的Spring 框架技術(shù)來定義您的beans以及其注入的依賴。 為了簡單起見沪么,我們經(jīng)常發(fā)現(xiàn)使用 @ComponentScan
找到你的bean硼婿,結(jié)合 @Autowired
構(gòu)造函數(shù)注入效果很好。
如果您按照上述建議(將應(yīng)用程序類放在根包中)構(gòu)建代碼禽车,則可以添加 @ComponentScan
而不使用任何參數(shù)寇漫。 所有應(yīng)用程序組件(@Component
,@Service
殉摔,@Repository
州胳,@Controller
等)將自動注冊為Spring Bean。
以下是一個使用構(gòu)造函數(shù)注入獲取必需的 RiskAssessor
bean的 @Service
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字段標記為final腐缤,表示隨后不能更改。
18. 使用 @SpringBootApplication注解
許多Spring Boot開發(fā)人員總是使用@Configuration
肛响,@EnableAutoConfiguration
和@ComponentScan
來標注它們的main類岭粤。 由于這些注釋經(jīng)常一起使用(特別是如果您遵循上述最佳實踐),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. 運行您的應(yīng)用
將應(yīng)用程序打包成jar并使用內(nèi)嵌的HTTP服務(wù)器的最大優(yōu)點之一就是你可以像其他方式那樣運行你的應(yīng)用猎物。 調(diào)試Spring Boot應(yīng)用程序也很容易; 您不需要任何特殊的IDE插件或擴展虎囚。
| 本節(jié)僅涵蓋基于jar的打包,如果您選擇將應(yīng)用程序打包為war文件蔫磨,則應(yīng)參考您的服務(wù)器和IDE文檔淘讥。
19.1 從一個IDE運行
您可以從IDE運行一個Spring Boot應(yīng)用如同一個簡單的Java應(yīng)用。然而堤如,第一步你將需要導入你的項目蒲列。導入步驟取決于您的IDE和構(gòu)建系統(tǒng)將有所變化。 大多數(shù)IDE可以直接導入Maven項目搀罢,例如Eclipse用戶可以從 File
菜單中選擇 Import…?
→ Existing Maven Projects
蝗岖。
如果您無法將項目直接導入到IDE中,則可以使用構(gòu)建插件生成IDE元數(shù)據(jù)榔至。 Maven包括 Eclipse 和 IDEA 的插件; Gradle為各種IDE提供插件抵赢。
| 如果你偶然運行了一個web 應(yīng)用兩次,將會看到一個“端口已在使用”的錯誤。STS用戶可以使用Relaunch
(重新啟動)按鈕而不是運行铅鲤,以確保任何現(xiàn)有實例已關(guān)閉划提。
19.2作為一個打包應(yīng)用運行
如果你在使用Spring Boot Maven或Gradle插件創(chuàng)建一個可執(zhí)行的jar,你可以使用 java -jar
運行你的應(yīng)用彩匕。例如:
$ java -jar target/myproject-0.0.1-SNAPSHOT.jar
它也可以以啟用遠程調(diào)試支持腔剂,運行一個打包應(yīng)用。這允許你附加一個調(diào)試器到你的打包應(yīng)用中:
$ 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插件包含一個 run
目標驼仪,可用于快速編譯和運行應(yīng)用程序掸犬。應(yīng)用像在你的IDE中一樣,運行在一個exploded 形式中:
$ mvn spring-boot:run
您可能還需要使用有用的操作系統(tǒng)環(huán)境變量:
$ export MAVEN_OPTS=-Xmx1024m -XX:MaxPermSize=128M
19.4 使用Gradle插件
Spring Boot Gradle 插件也包含一個 bootRun
任務(wù)绪爸,用于將你的應(yīng)用運行在一個 exploded 形式中湾碎。當你導入 spring-boot-gradle-plugin
后,這個 bootRun
任務(wù)都會被添加:
$ gradle bootRun
您可能還需要使用有用的操作系統(tǒng)環(huán)境變量:
$ export JAVA_OPTS=-Xmx1024m -XX:MaxPermSize=128M
19.5 熱插拔
由于Spring Boot應(yīng)用只是普通的Java應(yīng)用奠货,所以JVM熱插拔應(yīng)該開箱即用介褥。JVM熱插拔可替的節(jié)碼有些限制,為了更完整的解決方案递惋,JRebel 或 Spring Loaded 可以被使用柔滔。spring-boot-devtools
模塊也包含快速重新啟動應(yīng)用的支持。
有關(guān)詳細信息萍虽,請參閱下面第20章 開發(fā)者工具部分睛廊,以及Hot swapping “How-to”的內(nèi)容。
20. 開發(fā)者工具
Spring Boot 包含一個額外的工具集杉编,可以使應(yīng)用開發(fā)體驗更加愉快超全。spring-boot-devtools
模塊可以包含在任何模塊中,以提供額外的development-time特性邓馒。要包含devtools支持嘶朱,只需添加模塊依賴到你的構(gòu)建中:
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")
}
| 運行完全打包的應(yīng)用程序時,開發(fā)者工具將自動禁用光酣。 如果您的應(yīng)用程序是使用java -jar
啟動的疏遏,或者是使用特殊的類加載器啟動,那么它被認為是“生產(chǎn)應(yīng)用程序”救军。將依賴標記為可選的(optional
)是一種最佳做法改览,防止devtools 通過傳遞性應(yīng)用到項目中的其他模塊。Gradle不支持開箱即用的可選依賴缤言,因此在此期間您可能想要看一看propdeps-plugin
。
| 默認情況下重新打包檔案不包含devtools视事。如果你想使用某些遠程devtools特性胆萧,你需要禁用excludeDevtools
構(gòu)建屬性去包含它。Maven 和 Gradle插件都支持該屬性。
20.1 默認屬性
Spring Boot 支持的幾個庫使用緩存來提高性能跌穗。 例如订晌,模板引擎將緩存編譯的模板,以避免重復解析模板文件蚌吸。 此外锈拨,Spring MVC可以在服務(wù)靜態(tài)資源時向響應(yīng)中添加HTTP緩存頭。
雖然緩存在生產(chǎn)中是非常有利的羹唠,但它在開發(fā)過程中可能會產(chǎn)生反效果奕枢,阻止您看到剛剛在應(yīng)用程序中進行的更改。 由于這個原因佩微,spring-boot-devtools將默認禁用這些緩存選項缝彬。
緩存項通常通過設(shè)置 application.properties
文件進行配置。例如哺眯,Thymeleaf 提供了 spring.thymeleaf.cache
屬性谷浅。spring-boot-devtools
模塊將自動應(yīng)用合理的 development-time 配置,而不是需要手動設(shè)置這些屬性奶卓。
| 有關(guān)被應(yīng)用屬性的完整列表一疯,請參閱DevToolsPropertyDefaultsPostProcessor。
20.2 自動重啟
使用 spring-boot-devtools
的應(yīng)用夺姑,每當類路徑下的文件改變時墩邀,將會自動重新啟動。這在一個IDE中工作可能是一個有用的特性瑟幕,因為它為代碼更改提供了非晨钠眩快的反饋循環(huán)。默認情況下只盹,任何在類路徑下指向一個文件夾的實體辣往,將會被監(jiān)控其改變。注意殖卑,某些資源比如靜態(tài)資源和視圖模版不需要重啟應(yīng)用站削。
觸發(fā)重啟
由于DevTools 監(jiān)控類路徑資源,所以觸發(fā)重啟的唯一方式是更新classpath孵稽。引起classpath被更新的方式取決于你正在使用的IDE许起。
在Eclipse中,保存修改的文件將導致類路徑被更新并觸發(fā)重新啟動菩鲜。在IntelliJ IDEA中园细,構(gòu)建項目(`Build→Make Project`)將具有相同的效果。
| 你也可以通過受支持的構(gòu)建插件(即Maven和Gradle)啟動你的應(yīng)用接校,只要fork被啟用猛频,因為Devtools需要一個隔離的應(yīng)用類加載器執(zhí)行正確的操作狮崩。當Gradle 和 Maven檢測到Devtools在classpath下,會默認執(zhí)行這些鹿寻∧啦瘢【譯者注:未懂作者原意,以后再補充】
| 當和LiveReload一起使用時毡熏,自動重啟功能非常好坦敌。詳見下文,如果你使用JRebel痢法,自動重啟將被禁用以有利于動態(tài)重新加載類狱窘。其他devtools 特性(例如LiveReload 和 屬性重寫)仍然可以被使用。
| DevTools 依靠應(yīng)用上下文的關(guān)閉鉤子疯暑,關(guān)閉在重新啟動過程中的應(yīng)用训柴。如果你禁用關(guān)閉鉤子,它將不會正確的工作(SpringApplication.setRegisterShutdownHook(false)
)妇拯。
| 在決定classpath下的一個實體改變后幻馁,是否應(yīng)該觸發(fā)重新啟動時,DevTools 自動忽略名為spring-boot
,spring-boot-devtools
,spring-boot-autoconfigure
,spring-boot-actuator
,spring-boot-starter
的項目越锈。
重新啟動和重新加載
Spring Boot提供重新啟動技術(shù)仗嗦,它通過使用兩個類加載器工作的。 不改變的類(例如甘凭,來自第三方j(luò)ar的)被加載到基類加載器中稀拐。 您正在積極開發(fā)的類被加載到重新啟動類加載器中。 當應(yīng)用程序重新啟動時丹弱,重新啟動類加載器將被丟棄德撬,并創(chuàng)建一個新的類加載器。 這種方法意味著應(yīng)用程序重新啟動通常比“冷啟動”快得多躲胳,因為基類加載器已經(jīng)可用并且它加載的類很多(populated)蜓洪。
如果發(fā)現(xiàn)重新啟動對于你的應(yīng)用來說不夠快,或遇到類加載問題坯苹,您可以考慮重新加載技術(shù)例如ZeroTurnaround的JRebel隆檀。 這些工作通過改寫他們加載的類,使它們更適合重載粹湃。 Spring Loaded提供了另一個選項恐仑,然而它不支持盡可能多的框架髓梅,并且不是商業(yè)上支持的咐柜。
20.2.1 排除資源
某些資源在更改時不一定需要觸發(fā)重新啟動蛮寂。例如沟优,Thymeleaf 模版可以隨時編輯。默認情況下惊畏,更改/META-INF/maven
归斤,/META-INF/resources
偎痛,/resources
,/static
构捡,/public
或/templates
中的資源不會觸發(fā)重新啟動,但會觸發(fā)實時重新加載壳猜。如果要自定義這些排除項勾徽,可以使用spring.devtools.restart.exclude屬性。 例如统扳,要僅排除/ static和/ public喘帚,您將設(shè)置以下內(nèi)容:
spring.devtools.restart.exclude=static/**,public/**
| 如果要保留這些默認值并添加其他排除項,請改用spring.devtools.restart.additional-exclude
屬性咒钟。
20.2.2 監(jiān)視其他路徑
當您對不在類路徑中的文件進行更改時吹由,可能需要重新啟動或重新加載應(yīng)用程序。 為此朱嘴,請使用 spring.devtools.restart.additional-paths
屬性來配置其他路徑以監(jiān)視更改倾鲫。 您可以使用上述的 spring.devtools.restart.exclude
屬性來控制附加路徑下的更改是否會觸發(fā)完全重新啟動或只是實時重新加載。
20.2.3 禁用重新啟動
如果不想使用重新啟動特性萍嬉,可以使用 spring.devtools.restart.enabled
屬性來禁用它乌昔。 在大多數(shù)情況下,您可以在 application.properties
中設(shè)置此項(這仍將初始化重新啟動類加載器壤追,但不會監(jiān)視文件更改)磕道。
如果您需要完全禁用重新啟動支持,例如行冰, 因為它不適用于特定庫溺蕉,則需要在調(diào)用 SpringApplication.run(...)
之前設(shè)置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
設(shè)置為全局設(shè)置徘层,以使所有項目以相同的方式表現(xiàn)峻呕。
20.2.5 自定義重新啟動類加載器
如上面的 Restart vs Reload 部分所述,重新啟動功能是通過使用兩個類加載器實現(xiàn)的趣效。 對于大多數(shù)應(yīng)用程序瘦癌,此方法運行良好,但有時可能會導致類加載問題跷敬。
默認情況下讯私,IDE中的任何打開的項目將使用“重新啟動”類加載器加載,任何常規(guī) .jar
文件將使用“base”類加載器加載西傀。 如果您在多模塊項目上工作斤寇,并且不是每個模塊都導入到IDE中,則可能需要自定義一些東西拥褂。 為此娘锁,您可以創(chuàng)建一個 META-INF/spring-devtools.properties
文件。
spring-devtools.properties
文件可以包含前綴是 restart.exclude.
和 restart.include.
的屬性饺鹃。include
元素是應(yīng)該被拉入“restart”類加載器的項目莫秆,而且“exclude”元素是應(yīng)該向下推入“base”類加載器的項目。 屬性的值是將應(yīng)用于類路徑的正則表達式模式尤慰。
例如:
restart.exclude.companycommonlibs=/mycorp-common-[\\w-]+\.jar
restart.include.projectcommon=/mycorp-myproj-[\\w-]+\.jar
| 所有屬性鍵必須是唯一的馏锡。 只要一個屬性以restart.include.
或restart.exclude.
開頭都將會考慮。
| 所有的META-INF/spring-devtools.properties
將從classpath 被加載伟端。你可以把文件打包到你的項目杯道,或項目消耗的庫中。
20.2.6 已知限制
重新啟動功能不是工作的很好對于使用標準 ObjectInputStream
反序列化的對象责蝠。 如果需要反序列化數(shù)據(jù)党巾,可能需要使用Spring的 ConfigurableObjectInputStream
與 Thread.currentThread().getContextClassLoader()
組合使用。
不幸的是霜医,個別的第三方庫在不考慮上下文類加載器的情況下反序列化齿拂。 如果您發(fā)現(xiàn)這樣的問題,您需要向原始作者請求修復肴敛。
20.3 實時重新加載
spring-boot-devtools模塊包含一個內(nèi)嵌的LiveReload服務(wù)器署海,可以在資源更改時用于觸發(fā)瀏覽器刷新。 LiveReload瀏覽器擴展程序可以從livereload.com免費提供給Chrome医男,F(xiàn)irefox和Safari砸狞。
如果您不想在應(yīng)用程序運行時啟動LiveReload服務(wù)器,則可以將 spring.devtools.livereload.enabled
屬性設(shè)置為 false
镀梭。
| 你只能一次運行一個LiveReload服務(wù)器刀森。 應(yīng)用啟動之前,請確保沒有其他LiveReload服務(wù)器正在運行报账。 如果從IDE啟動多個應(yīng)用程序研底,則只有第一個應(yīng)用程序?qū)⒂蠰iveReload的支持埠偿。
20.4 全局設(shè)置
您可以通過向 $HOME
文件夾添加名為 .spring-boot-devtools.properties
的文件來配置全局devtools設(shè)置(請注意,文件名以“.”開頭)榜晦。 添加到此文件的任何屬性將應(yīng)用到您的計算機上使用devtools的 所有 Spring Boot應(yīng)用程序冠蒋。 例如,總是使用觸發(fā)器文件配置重新啟動乾胶,您可以添加以下內(nèi)容:
~/.spring-boot-devtools.properties.
spring.devtools.reload.trigger-file=.reloadtrigger
20.5 遠程應(yīng)用
Spring Boot開發(fā)者工具不僅限于本地開發(fā)浊服。 當運行遠程應(yīng)用時也可以使用幾個功能。 遠程支持是可選的胚吁,要啟用它你需要確保 devtools
被包含在打包存檔中:
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<!-- 譯者注:排除屬性設(shè)置為false,即把devtools在打包插件中-->
<excludeDevtools>false</excludeDevtools>
</configuration>
</plugin>
</plugins>
</build>
然后你需要設(shè)置一個 spring.devtools.remote.secret
屬性,例如:
spring.devtools.remote.secret=mysecret
spring-boot-devtools
是一種安全隱患愁憔。 您絕不能在生產(chǎn)部署中啟用它的支持腕扶。
遠程devtools支持分為兩部分: 有一個接受連接的服務(wù)器端端點,還有一個您在IDE中運行的客戶端應(yīng)用吨掌。 當 spring.devtools.remote.secret
屬性設(shè)置后半抱,服務(wù)器組件將自動啟用。但是客戶端組件必須手動啟動膜宋。
20.5.1 運行遠程客戶端應(yīng)用
設(shè)計遠程客戶端應(yīng)用旨在從IDE中運行窿侈。 您需要使用與正在連接的遠程項目相同的類路徑運行 org.springframework.boot.devtools.RemoteSpringApplication
。 傳遞給應(yīng)用程序的非選項參數(shù)應(yīng)該是您要連接到的遠程URL秋茫。
例如史简,如果您使用Eclipse或STS,并且有一個名為 my-app
的項目已部署到Cloud Foundry肛著,則將執(zhí)行以下操作:
- 從
Run
菜單選擇Run Configurations…?
- 創(chuàng)建一個新的
Java Application
"啟動配置" - 瀏覽
my - app
項目 - 使用
org.springframework.boot.devtools.RemoteSpringApplication
作為主類 - 添加
https://myapp.cfapps.io
(或任何您的遠程URL) 到Program arguments
一個運行中的遠程客戶端將看起來像:
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ ___ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | | _ \___ _ __ ___| |_ ___ \ \ \ \
\\/ ___)| |_)| | | | | || (_| []::::::[] / -_) ' \/ _ \ _/ -_) ) ) ) )
' |____| .__|_| |_|_| |_\__, | |_|_\___|_|_|_\___/\__\___|/ / / /
=========|_|==============|___/===================================/_/_/_/
:: 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
屬性如何被讀取并傳遞到服務(wù)器進行認證的原因枢贿。
| 始終建議使用https://作為連接協(xié)議殉农,以便傳輸被加密,并且密碼不能被攔截局荚。
spring.devtools.remote.proxy.host
和 spring.devtools.remote.proxy.port
屬性。
20.5.2 遠程更新
遠程客戶端將以與 本地重新啟動 相同的方式監(jiān)控你的應(yīng)用類路徑的更改耀态。 任何更新的資源將被推送到遠程應(yīng)用轮傍,并且(如果需要)觸發(fā)重新啟動。 如果您正在使用您本地沒有的云服務(wù)迭代功能茫陆,這可能會是相當有用的金麸。 通常,遠程更新和重新啟動比完全重建和部署周期要快得多簿盅。
| 僅在遠程客戶端運行時文件才被監(jiān)控挥下。 如果在啟動遠程客戶端之前更改文件揍魂,則不會將其推送到遠程服務(wù)器。
20.5.3 遠程調(diào)試通道
在一個遠程應(yīng)用診斷問題時棚瘟,Java遠程調(diào)試非常有用现斋。 不幸的是,當您的應(yīng)用程序部署在數(shù)據(jù)中心之外時偎蘸,并不總是可以啟用遠程調(diào)試庄蹋。 如果您正在使用基于容器的技術(shù)(如Docker),遠程調(diào)試也可能難以設(shè)置迷雪。
為了幫助解決這些限制限书,devtools 支持基于HTTP的遠程調(diào)試通道 ,遠程客戶端提供一個在端口8000的本地server章咧,您可以連接遠程調(diào)試器倦西。 一旦建立連接后,調(diào)試信息通過HTTP被發(fā)送到遠程應(yīng)用赁严。 如果要使用其他端口扰柠,可以使用 spring.devtools.remote.debug.local-port
屬性進行設(shè)置。
你需要確保遠程應(yīng)用啟動時疼约,已啟用遠程調(diào)試功能卤档。通常可以通過配置 JAVA_OPTS
來實現(xiàn)程剥。 例如劝枣,使用Cloud Foundry,您可以將以下內(nèi)容添加到 manifest.yml
中:
---
env:
JAVA_OPTS: "-Xdebug -Xrunjdwp:server=y,transport=dt_socket,suspend=n"
address=NNNN
選項給 -Xrunjdwp
哨免。 如果它被忽略了,Java將簡單地選擇一個隨機可用端口昙沦。
Preferences…?
選擇 Java
→ Debug
,將 Debugger timeout (ms)
更改為更合適的值(大多數(shù)情況下丘损,60000可以正常工作)普办。
21. 為生產(chǎn)打包您的應(yīng)用
可執(zhí)行的jar可用于生產(chǎn)部署撬陵。 由于它們是獨立的珊皿,所以它們也非常適合基于云的部署。
對于其他“生產(chǎn)就緒”功能巨税,如健康蟋定,審計和測量REST或JMX端點; 考慮添加 spring-boot-actuator
。 有關(guān)詳細信息草添,請參見 第五部分. Spring Boot 執(zhí)行器: Production-ready 功能溢吻。
22. 接下來閱讀什么
隨著你應(yīng)該遵循的一些最佳實踐,現(xiàn)在應(yīng)該對如何使用Spring Boot 有一個很好的理解果元。您現(xiàn)在可以繼續(xù)深入學習關(guān)于Spring Boot 特性具體內(nèi)容,或者您可以跳過犀盟,去閱讀關(guān)于Spring Boot“生產(chǎn)就緒”方面的內(nèi)容而晒。
第三部分翻譯完畢,繼續(xù)閱讀請移步到這里