領先一步
VMware 提供培訓和認證,助您加速進步。
瞭解更多最近,James Ward 寫了一篇很棒的博文,題為 “Java 不爛——只是你用錯了”,其中強調了企業級 Java 開發人員在日常構建 Java 應用程式時面臨的諸多挑戰。好訊息是,擺脫開發困境比你想象的要容易得多。在過去的幾年裡,Spring 重新定義了現代 Java 應用程式的構建方式,同時顯著提高了開發速度。在這篇文章中,我將以 James Ward 的博文為背景,解釋 Spring 如何幫助開發人員在 JVM 上(使用 Java)大顯身手,同時解決 James 提出的每個問題。
##即時開發環境設定非常棒 在 James 的部落格中,他斷言“10 頁的 Wiki 來設定開發環境很糟糕”。我們都在職業生涯的某個時刻建立過這些 Wiki 頁面,並費力地嘗試保持它們更新。這些 Wiki 長期以來一直是新團隊成員的挫敗感來源,因為它們經常充斥著過時資訊。好訊息是,Spring Boot 的構建支援使得自動化此過程變得相當容易。
從現有應用程式開始,就像克隆原始碼倉庫並執行應用程式一樣簡單。Spring Boot 支援 Java 最流行的構建工具,Maven 和 Gradle。使用你最喜歡的構建工具執行一個功能齊全的應用程式就像
Maven 示例
mvn spring-boot:run
Gradle 示例
gradle bootRun
由於 Spring Boot 應用程式是一個自包含的工作負載,它將應用程式程式碼、伺服器和第三方依賴項組合成一個單一的構建和部署單元(可執行的 .jar 檔案),因此無論使用何種 IDE,開發團隊都能確保獲得直接、可重複的開發體驗。開發人員擺脫了繁瑣的環境設定說明,可以專注於構建出色的應用程式。在構建之外執行 Spring Boot 應用程式可以透過執行以下命令來完成:
java -jar target/my-application-1.0.1-SNAPSHOT.jar
提示:想自己嘗試一下嗎?請在 spring.io 上的眾多 入門指南 中進行學習。對於 Spring Boot 的新手,一個很好的起點是 使用 Spring Boot 構建應用程式 指南。
##一致的部署環境非常棒 James Ward 強調的下一個挑戰是“為了在將構建從開發環境提升到 staging 環境再到生產環境時最大限度地降低風險,每個環境之間唯一應該改變的只有配置”。手動修改部署工件是災難的根源,最終會導致部署延遲或失敗。特定於環境的配置應該外部化,確保在開發環境中測試的相同程式碼是進入生產環境的“黃金副本”。這是證明你所測試的就是你所部署的唯一經濟有效的方法!
Spring Boot 使用一種非常特殊的 PropertySource 順序,使得外部化配置變得輕而易舉,該順序旨在允許對值進行合理的覆蓋。通常,最好在專案中為本地開發提供預設配置,但在將程式碼提升到不同環境時覆蓋這些值。Spring Boot 透過命令列引數、JNDI 屬性、Java 系統屬性、作業系統環境變數、配置檔案、基於配置檔案的配置變體以及更多方式,提供對外部化配置的全面支援。Spring Boot 對環境變數的支援使得遵循 十二因素應用配置最佳實踐(程式碼與配置嚴格分離)變得輕而易舉。
提示 1:當使用像 Cloud Foundry 這樣的雲平臺時,Spring Boot 應用程式可以利用 Spring Cloud Connectors 自動繫結到 Cloud Foundry 服務,如資料庫和訊息系統。這具有減少應用程式需要維護的環境特定配置屬性數量的優勢,從而顯著降低在跨環境提升程式碼時出錯的風險。
提示 2:好奇十二要素應用程式為何重要?請檢視這篇博文,為什麼十二要素應用程式模式、微服務和 CloudFoundry 很重要。
##快速伺服器啟動非常棒 Spring Boot 支援輕量級、嵌入式容器/伺服器,這些容器/伺服器啟動迅速。一個簡單的 REST 應用程式可以在短短 3 秒內啟動。截至 Spring Boot 1.2,支援嵌入式應用程式伺服器包括 Tomcat(預設容器)、Jetty 和 Undertow。Spring Boot 不僅為領先的輕量級容器提供支援,而且透過使其易於替換預設容器,使開發人員完全掌控這些決策。
以下 Gradle 構建配置支援全棧 Web 開發,包括對嵌入式 Tomcat 和 spring-webmvc 的支援。
Gradle 示例
...
apply plugin: 'java'
repositories { jcenter() }
dependencies {
compile("org.springframework.boot:spring-boot-starter-web:1.2.0.RELEASE")
}
...
正如 James Ward 在他最初的部落格文章中指出的,透過將單體部署分解為微服務,可以進一步縮短啟動時間。在這篇文章的後面,將更詳細地討論微服務的主題(參見標題為 微服務風格架構非常棒 的部分)。
現代開發人員需要工具和技術,使他們能夠以最少的摩擦快速上手。他們還要求模組化、輕量級和有主見的技術來最佳化生產力。Spring Boot 旨在解決快速啟動並顯著提高開發速度的問題。
正如 James Ward 正確指出的那樣,“如果你的任何庫依賴項沒有由構建工具管理,那將很糟糕”。Spring Boot 不僅支援現代構建技術,還透過提供方便的依賴項描述符,即 starter POMS,使這種最佳實踐成為首要實踐。Starter POMs 為常見的開發工作負載提供了一組依賴項,你可以簡單地將其包含在你的應用程式中。
要開始使用 Spring Boot,你可以將瀏覽器指向 Spring Initializer - http://start.spring.io。Spring Initializer 提供了一個基於 Web 的介面,允許開發人員選擇應用程式/工作負載和相關依賴項。然後,它將生成一個具有構建支援的啟動應用程式(支援 Maven POM、Maven 專案、Gradle Config、Gradle 專案)。
Spring Initializer 截圖:
對於喜歡命令列介面的開發人員,您可以透過以下命令安裝 Spring Boot CLI:
curl http://start.spring.io/install.sh | sh
一個新專案可以透過命令列簡單地透過以下命令初始化:
spring init --dependencies=web,data-jpa my-project
透過 Spring Initializer 或 Boot CLI 完成的初始化,其結果是一個功能齊全的應用程式,其中所需的依賴項已由 Spring Boot 自動包含和配置。
Spring IO Platform(包括 Spring Boot)也提供了 Spring Boot starter POMs 管理的依賴項的超集。Spring IO 在整個 Spring 組合中統一了依賴項版本,並且比 Spring Boot 有更長的釋出週期,這為企業提供了一個經過測試且已知可以協同工作的依賴項版本快照。Spring IO Platform 分發版並非是庫的單一整體下載,開發人員可以自由選擇應用程式中所需的部件。Spring IO Platform 分發版包含 Spring 模組、測試庫、日誌框架、資料庫管理、SQL/No-SQL 等等。Spring IO 分發版非常適合希望以更漸進的速度消費 Spring IO Platform 依賴項的企業。
以下 Gradle 配置演示瞭如何配置 Spring IO Platform 物料清單並利用 Spring Boot 的 web starter POM:
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'io.spring.gradle:dependency-management-plugin:0.3.0.RELEASE'
}
}
apply plugin: 'io.spring.dependency-management'
repositories {
mavenCentral()
}
dependencyManagement {
imports {
mavenBom 'io.spring.platform:platform-bom:1.1.0.RELEASE'
}
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter-web'
}
##短開發/驗證週期確實很棒 大多數現代應用程式都使用與後端服務通訊的豐富使用者介面構建。以這種方式構建應用程式的好處是 UI 和伺服器端邏輯之間實現了強分離。大多數現代 IDE 都提供靜態資源的動態重新載入,允許開發人員在不重新啟動伺服器的情況下檢視更改。
Spring Boot 還支援伺服器端模板技術,如 Thymeleaf、Freemarker 和 Groovy。Spring Boot 允許這些模板技術的動態重新載入,而無需重新啟動伺服器。對於 Thymeleaf,這就像在 application.properties 檔案中設定以下屬性一樣簡單:
spring.thymeleaf.cache: false
在伺服器端,將您的單體應用程式分解為微服務將減少 Spring Boot 應用程式的啟動時間(由於其使用了輕量級嵌入式容器,啟動時間已經相當快)。此外,Spring Boot 還支援測試實用程式的自動配置。啟用 Boot 的測試自動配置就像包含 spring-boot-starter-test starter POM 一樣簡單。這使 Spring Test、JUnit、Hamcrest 和 Mockito 依賴項得以啟用,從而輕鬆地將測試驅動開發 (TDD) 納入日常工作流程。TDD 使開發人員能夠立即獲得對其程式碼更改的反饋。
最後,JRebel 為類重新載入提供了全面的支援,支援 80 多種 Java 框架(包括 Spring)。請檢視 Josh Long 和 Adam Koblentz 的網路研討會 Spring Boot and JRebel 6 獲取更多詳細資訊。
##微服務風格的架構很棒 James 的“單體釋出很糟糕”的說法對於大型或複雜的分散式系統來說是完全正確的。大多數開發人員希望以更迭代的方式(敏捷)工作並更頻繁地釋出。微服務風格的架構作為對抗單體應用程式挑戰的一種方式而日益流行。對於微服務新手,Martin Fowler 在他的部落格中對這種架構風格提供了很好的描述。
在構建分散式應用程式(包括微服務風格的應用程式)時,會出現許多常見的系統模式。Spring Cloud 透過提供開箱即用的服務來應對最常見的挑戰,從而簡化了這些模式的採用。Spring Cloud 實現了配置管理、服務發現、熔斷器、智慧路由、微代理和控制匯流排等模式。Spring Boot 使將這些功能整合到您的應用程式中變得異常簡單。
例如,Spring Cloud Netflix 專案使使用 Netflix 的 Eureka 搭建服務發現服務變得像這樣簡單:
@SpringBootApplication
@EnableEurekaServer
public class Application {
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
客戶端應用程式只需使用 @EnableEurekaClient 即可註冊為 Eureka 客戶端
@SpringBootApplication
@EnableEurekaClient
@RestController
public class Application {
@RequestMapping("/")
public String home() {
return "Hello world";
}
public static void main(String[] args) {
new SpringApplicationBuilder(Application.class).web(true).run(args);
}
}
提示 1:Spring Cloud 為眾多分散式處理模式提供支援。為了幫助您入門,請檢視 Spring Cloud Samples GitHub 倉庫。Dave Syer 和 Spencer Gibb 的 Spring Cloud, Spring Boot and Netflix OSS SpringOne 會話是瞭解和學習如何操作微服務風格架構的另一個好方法。
提示 2:如果您正在構建超媒體風格的 REST API,請務必查閱入門指南 使用 REST 訪問 JPA 資料。Spring Data REST 將幫助您的服務開發加速。Spring Data REST 支援 SQL 和 No-SQL 倉庫。
擁有能讓您快速編寫微服務的技術只是成功的一半。開發人員經常被將程式碼部署到生產平臺中的各種延誤所困擾。一些最常見的障礙包括手動部署、測試、基礎設施配置和服務配置。持續交付旨在自動化將程式碼推廣到生產環境的過程,同時最大限度地降低風險。這使得組織能夠對應用程式進行增量更改,使部署成為業務決策而不是資源決策。這本身就是一個很大的話題,但我強烈推薦 Matt Stine 的演講,使用 Spring 和 Cloud Foundry 為 PaaS 開發微服務,該演講出色地強調了將敏捷工程實踐與 Pivotal Cloud Foundry 的自動化相結合的好處。
##無狀態應用程式很棒 James 指出“粘性會話和伺服器狀態通常是扼殺你的效能和彈性的最佳方式之一。會話狀態(在傳統的 Servlet 意義上)使得持續交付和水平擴充套件變得非常困難。”
從應用程式中移除會話狀態可以顯著簡化操作,允許應用程式在無需擔心丟失會話資料的情況下進行重新部署、終止或擴充套件。存在維護狀態的有效用例,例如共享身份驗證狀態,但此狀態應持久化在應用程式之外(通常在高效能儲存庫中,如 NoSQL、分散式快取甚至記憶體資料儲存中)。外部化應用程式狀態不一定是一項繁重的工作,Spring Session 提供了通用的基礎設施,使此過程變得簡單和可移植。Spring Session 提供了:
使用 Redis 配置 Spring Session 就像這樣簡單:
@EnableRedisHttpSession
public class Config {
@Bean
public JedisConnectionFactory connectionFactory() {
return new JedisConnectionFactory();
}
}
提示:Spring Session 1.0 最近 釋出了 GA 版本,所以請嘗試 Spring Session 示例,親眼看看它的實際應用。Dave Syer 最近發表了一篇題為 API 閘道器模式:Angular JS 和 Spring Security 第四部分 的部落格文章,其中詳細介紹了共享身份驗證狀態的用例。強烈推薦閱讀!
最後,如果您正在使用 Pivotal Cloud Foundry,Cloud Foundry Java build pack 提供了另一種選擇,透過自動配置的 CF 會話狀態儲存來輕鬆外部化狀態。有關詳細資訊,請檢視這篇 博文。
##非阻塞應用很棒 許多現代應用架構都可以從請求的非同步和非阻塞處理中大大受益。這些用例可能包括組合多個後端服務呼叫和 WebSocket 風格的應用。
Reactor 專案(Spring IO Platform 的一部分)為構建這些非同步、非阻塞應用程式提供了基礎。在 2.0 版本中,Reactor 將提供 Reactive Streams 規範 的完整實現,這將開啟與 Akka Streams、Ratpack、RxJava 等其他 Reactive Streams 實現的整合。
以下程式碼片段展示瞭如何使用 Reactive Streams API 建立流,向其中新增業務邏輯,然後向其中釋出資料:
// by default Streams use the Disruptor RingBufferDispatcher
Broadcaster<String> helloStream = Streams.broadcast(env);
helloStream.map(s -> "Hello " + s + "!")
.consume(log::info);
helloStream.onNext("World");
提示:Spring Boot 為 Reactor 專案提供支援,使其易於上手。請按照 使用 Reactor 建立非同步事件驅動應用程式 入門指南來建立您的第一個響應式應用程式。另外,請務必檢視網路研討會 使用 Reactor 進行非同步、非阻塞微服務開發。
Spring Framework 4 引入了對 WebSocket 風格、事件驅動應用程式的支援。這種務實的方法遠遠超越了 JSR-356,幷包括帶有 SockJS 的客戶端回退選項、對訊息子協議 (STOMP) 的支援、安全性 (Spring Security 4)、訊息代理支援、基於 Reactor 的 MessageChannel 用於訊息傳遞、客戶端斷開連線處理以及熟悉的 Spring 程式設計模型。
提示:Spring Boot 使 WebSocket 應用程式的配置變得輕而易舉。按照 使用 WebSocket 構建互動式 Web 應用程式指南 開始吧。
Spring Boot 為開發人員提供了使用 Java 6、7、8 以及 Groovy 構建下一代應用程式的選項。在 James 的文章中,他指出“Java 語言有點糟糕”,但隨著 Java 8 的釋出,Java 得到了顯著發展,並提供了許多強大的語言特性,這將提高生產力。一些優秀的 Java 8 特性包括對 Lambda 表示式、Stream 和併發改進的支援。Spring Boot 使使用 Java 8 或 Groovy 變得輕鬆。
提示:如果您不熟悉 Java 8 的特性,我強烈推薦 Venkat Subramaniam 的書,Java 中的函數語言程式設計:駕馭 Java 8 Lambda 表示式的力量 以及他的 SpringOne2GX 2014 演講。
##結論 構建現代 Java 應用程式不必是一種痛苦的經歷。Spring Boot 消除了構建應用程式的繁文縟節,讓 Java 再次變得有趣。Spring 從應用程式的每一層——業務邏輯(Spring 基礎專案)、配置和執行時(Spring Boot)以及分散式系統模式(Spring Cloud)中消除了樣板程式碼。最好的入門方法是深入研究 Spring 的入門指南,並部署到 Pivotal Web Services(一個公共的、託管的 Cloud Foundry 版本,免費使用 60 天)。