領先一步
VMware 提供訓練和認證,以加速您的進展。
瞭解更多Spring Tool Suite 3.6.4 上週剛發佈。這篇部落格文章是一個教學,示範 STS 提供的一些新功能,以建立和使用 Spring Boot 應用程式。
在本教學中,您將學習如何
我們使用「新增 Spring Starter」精靈來建立一個基本的 Spring Boot 應用程式。
Spring Boot 提供了所謂的「starters」。Starter 是一組類別路徑相依性,它與 Spring Boot 自動組態結合,讓您可以開始使用應用程式,而無需進行任何組態。我們選擇了 'web' starter,因為我們將建置一個簡單的 'Hello' REST 服務。
此精靈是一個 GUI 前端,在幕後使用 start.spring.io 上的 Web 服務來產生一些基本骨架。您可以直接使用該 Web 服務,下載它產生的 zip 檔案,解壓縮它,匯入它等等。使用 STS 精靈只需按一下按鈕即可完成所有這些操作,並確保專案已正確組態,以便您可以立即開始編碼。
在您按一下「完成」按鈕後,您的工作區看起來會像這樣
由 start.spring.io 產生的 HelloBootApplication
Java-main 類別是目前我們應用程式中唯一的程式碼。感謝 Spring Boot 的「魔法」,並且因為我們將 'web' starter 新增到我們的相依性中,這段微小的程式碼已經是一個功能齊全的 Web 伺服器!它只是還沒有任何實際內容。在新增一些內容之前,讓我們先學習如何執行應用程式,並驗證它確實在執行中。
由精靈建立的 Spring Boot 應用程式有兩種風味:「jar」或「war」。Starter 精靈讓您在其「封裝」選項中選擇它們。Spring-boot 的一個很棒的功能是,您可以輕鬆地建立獨立的「jar」封裝專案,其中包含功能齊全的嵌入式 Web 伺服器。您只需執行應用程式的 Java Main 類型,就像執行任何其他純 Java 應用程式一樣即可。這是一個巨大的優勢,因為您不必費心設定本機或遠端 Tomcat 伺服器、war 封裝和部署。如果您真的想「硬著頭皮」做事,您仍然可以選擇「war」封裝。但是,實際上沒有必要這樣做,因為
注意:我們在這裡不會介紹如何將應用程式部署到 Cloud Foundry,但在這篇文章中,您可以了解更多關於使用 Cloud Foundry Eclipse 直接從您的 IDE 執行此操作的資訊。
現在,如果您理解我剛才說的話,那麼您可能會意識到,您實際上不需要 STS 的任何「特殊」工具來在本機執行應用程式。只需按一下 Java Main 類型,然後選取「執行身分 >> Java 應用程式」即可。此外,您的所有標準 Eclipse Java 偵錯工具都將「正常運作」。但是,STS 提供了一個專用的啟動器,它基本上做同樣的事情,但增加了一些有用的額外功能。因此,讓我們改用它。
您的應用程式應該會啟動,並且您應該會在主控台視窗中看到一些輸出
您可以開啟在本機執行的應用程式,網址為 https://127.0.0.1:8080。您只會得到一個 404
錯誤頁面,但這完全符合預期,因為我們尚未在我們的應用程式中新增任何實際內容。
現在,我承諾的額外功能呢?「執行身分 >> Boot 應用程式」幾乎是一個普通的 Java 啟動器,但提供了一些額外的選項來自訂它建立的啟動組態。若要查看這些選項,我們需要開啟「啟動組態編輯器」,可從 或
工具列按鈕存取
如果您使用過 Eclipse 中的 Java 啟動組態編輯器,這應該看起來很熟悉。對於 Boot 啟動組態,「主要」標籤有點不同,並且有一些額外的東西。我不會討論所有額外的功能,您可以在 STS 3.6.4 發行說明中找到更多資訊。因此,讓我們做一些簡單的事情,例如,將預設 HTTP 連接埠 8080
覆寫為其他連接埠,例如 8888
。您可能會猜到,這可以透過設定系統屬性來完成。在「純」Java 啟動器中,您可以透過命令列引數設定此類屬性。但是,您可能會想知道,該屬性的名稱究竟是「spring.port」、「http.port」還是「spring.server.port」?幸運的是,啟動組態編輯器會提供協助。「覆寫屬性」表格提供了一些基本的內容輔助。您只需輸入「port」,它就會提出一些建議
選取 server.port
,在右欄中新增值 8888
,然後按一下「執行」。
如果您完全依照步驟執行到此處,您的啟動可能會立即終止並出現例外狀況
Error: Exception thrown by the agent : java.rmi.server.ExportException: Port already in use: 31196; nested exception is:
java.net.BindException: Address already in use
這可能有點令人驚訝,因為我們剛剛變更了我們的連接埠,不是嗎?實際上,此處的連接埠衝突不是來自 HTTP 連接埠,而是用於啟用「即時 Bean 圖形支援」的 JMX 連接埠(我不會在這篇部落格文章中討論此功能,請參閱 STS 3.6.4 發行說明)。
我們可以做幾件事來避免錯誤。我們可以再次開啟編輯器並同時變更 JMX 連接埠,或者我們可以停用「即時 Bean 支援」。但可能我們真的不想在這種情況下執行多個應用程式副本。因此,我們應該在啟動新執行個體之前停止已在執行的執行個體。由於這是一件非常常見的事情,因此 STS 提供了一個 工具列按鈕,專門用於此目的。按一下按鈕,正在執行的應用程式將會停止並重新啟動,而您剛才對啟動組態所做的變更現在將生效。如果它運作正常,您現在應該會在
https://127.0.0.1:8888
而不是 8080
看到 404
錯誤頁面。(注意:如果您尚未啟動任何內容,則重新啟動按鈕將無法運作,因為它從您目前工作階段的啟動歷程記錄運作。但是,如果您至少啟動過一次應用程式,則可以「重新啟動」已終止的應用程式)
從啟動組態編輯器覆寫預設屬性值對於「快速覆寫」很方便,但長期而言,依靠此方法來組態許多屬性並管理更複雜的組態可能不是一個好主意。為此,最好在您可以提交到 SCM 的屬性檔案中管理屬性。Starter 精靈已經方便地為我們建立了一個空的 application.properties
。
為了協助您編輯 application.properties
,STS 3.6.4 提供了一個全新的 Spring 屬性編輯器。此編輯器提供良好的內容輔助和錯誤檢查
上面的螢幕擷取畫面顯示了一些「隨意操作」內容輔助和錯誤檢查。目前對於我們非常簡單的「錯誤頁面應用程式」而言,唯一有意義的屬性是 server.port
。嘗試在屬性檔案中變更連接埠,當您再次執行應用程式時,應該會自動擷取它。但是請注意,在啟動組態中覆寫的屬性優先於 application.properties
。因此,您必須取消勾選或刪除啟動組態中的 server.port
屬性才能看到效果。
讓我們讓我們的應用程式更有趣。以下是我們要做的
若要建立 REST 服務,您可以遵循本指南。Hover 我們正在做一些更簡單和更直接的事情。
繼續並建立一個包含此程式碼的控制器類別
package demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(@RequestParam String name) {
return "Hello "+name;
}
}
透過重新啟動 () 您的應用程式來試用此功能。URL
https://127.0.0.1:8888/hello?name=Kris
應該會傳回文字訊息「Hello Kris」。
這實際上很容易做到,您可能熟悉 Spring 的 @Value 註解。但是,使用 @Value
您將無法取得良好的內容輔助。Spring 屬性編輯器不會知道您以這種方式定義的屬性。若要了解原因,了解 Spring 屬性編輯器如何取得有關已知屬性的資訊會很有用。
從 1.2.x 版開始的一些 Spring Boot Jar 包含特殊的 JSON meta-data 檔案,編輯器會在您專案的類別路徑上尋找並剖析這些檔案。這些檔案包含有關已知組態屬性的資訊。如果您稍微挖掘一下,可以從 STS 找到這些檔案。例如,開啟「spring-boot-autoconfigure-1.2.2.RELEASE.jar」(在「Maven 相依性」下),然後瀏覽至「META-INF/spring-configuration-metadata.json」。您會在其中找到 server.port
等屬性的文件。
為了讓編輯器擷取我們自己的使用者定義屬性,我們必須建立此 meta data。幸運的是,如果您使用 Spring Boot @ConfigurationProperties 定義您的屬性,則可以輕鬆地自動化此操作。因此,定義一個像這樣的類別
package demo;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties("hello")
public class HelloProperties {
/**
* Greeting message returned by the Hello Rest service.
*/
private String greeting = "Welcome ";
public String getGreeting() {
return greeting;
}
public void setGreeting(String greeting) {
this.greeting = greeting;
}
}
@ConfigurationProperties("hello")
告知 Boot 採用以 hello.
開頭的組態屬性,並嘗試將它們注入到 HelloProperties
Bean 的對應 Bean 屬性中。@Component
註解標記此類別,以便 Spring Boot 在掃描類別路徑時會擷取它並將其轉換為 Bean。因此,如果組態檔案(或其他屬性來源)包含屬性 hello.greeting
,則該屬性的值將注入到我們 HelloProperties
Bean 的 setGreeting
中。
現在,若要實際使用此屬性,我們只需要對 Bean 的參考。例如,若要自訂 REST 服務傳回的訊息,我們可以將 @Autowired
欄位新增至 HelloController
並呼叫其 getGreeting
方法
@RestController
public class HelloController {
@Autowired
HelloProperties props;
@RequestMapping("/hello")
public String hello(@RequestParam String name) {
return props.getGreeting()+name;
}
}
再次重新啟動您的應用程式,並嘗試存取 https://127.0.0.1:8888/hello?name=yourname
。您應該會收到預設的「Welcome yourname」訊息。
現在,繼續嘗試編輯 application.properties
並將 greeting 變更為其他內容。雖然我們已經準備好一切來正確定義執行階段的屬性,但您會注意到編輯器仍然不知道我們新建立的屬性
為了讓編輯器知道,仍然缺少的是 spring-configuration-metadata.json
檔案。此檔案是在建置時由 spring-boot-configuration-processor
建立的,spring-boot-configuration-processor
是一個 Java 註解處理器。我們必須將此處理器新增至我們的專案,並確保它在專案建置期間執行。
將此新增至 pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
</dependency>
然後執行「Maven >> 更新專案」以觸發專案組態更新。由 STS 提供的 Maven 專案組態器將組態 JDT APT 並啟動 Eclipse 建置的處理器。警告將立即從編輯器中消失。您也會取得正確的 Hover Info
現在註解處理器已啟動,對您的 HelloProperties
類別的任何未來變更都將觸發 JSON meta-data 的自動更新。您可以透過新增一些額外屬性,或將您的 greeting
屬性重新命名為其他名稱來試用它。警告將視情況出現/消失。如果您好奇您的 meta-data 檔案在哪裡,您可以在 target/classes/META-INF
中找到它。該檔案就在那裡,即使 Eclipse 盡力向您隱藏它。Eclipse 對專案輸出資料夾中的所有檔案執行此操作。不過,您可以使用 Navigator
視窗來解決此問題,該視窗不會過濾太多檔案,並向您顯示工作區中實際資源的更直接檢視。透過「視窗 >> 顯示視窗 >> 其他 >> Navigator」開啟此視窗
注意:我們知道新增處理器的手動步驟似乎是不必要的複雜化。我們計劃在未來進一步自動化此操作。
希望您喜歡本教學。歡迎提出意見和問題。在另一篇即將發表的文章中,我將向您展示更多關於 @ConfigurationProperties
的進階用法,以及 STS 屬性編輯器如何支援它。