搶先一步
VMware 提供培訓和認證,以加速您的進展。
瞭解更多Spring Framework 5.0 的第五個也是最後一個里程碑的更新...
名稱 *Spring MVC* 廣為人知且被廣泛使用,但可能有些人會驚訝,實際上並沒有名為此名稱的專案或獨立發行版本。 相反地,它是 Spring Framework 發行版本中名為 `spring-webmvc` 的模組。 這是另一個小知識問題。您是否知道該模組中的頂層套件沒有 "mvc"? 相反地,它被稱為 `org.springframework.web.servlet`。 實際上,這些都是我們不必記住的細節。 重要的是我們有一個簡短且令人難忘的名稱來指代 *Spring 基於 Servlet 堆疊* 的 Web 框架。
Spring 的反應式堆疊 Web 框架是 5.0 中的新增功能,它具有完整的反應性和非阻塞性。 它適用於使用少量執行緒的事件迴圈樣式處理。 它在 Servlet 容器(Tomcat、Jetty、Servlet 3.1+)和非 Servlet 執行階段(Netty、Undertow)上都受支援,因為此堆疊的通用基礎不是 Servlet API,而是建立在反應式串流和 Reactor 專案上的非阻塞替代方案。 如果您想知道,Servlet 3.1 不是能夠進行非阻塞 I/O 嗎? 是的,它是,我們支援在 Servlet 3.1 容器上執行,但 Servlet API 的其餘部分是命令式樣式,無法在反應式、非阻塞堆疊中使用。
到目前為止,我們缺少反應式 Web 堆疊的專用名稱,該堆疊同時支援 Spring MVC 註釋(即 @Controller
、@RequestMapping
)和新的函數式程式設計模型,這使得討論和清楚地區分程式設計模型和堆疊具有挑戰性。 在我們的 milestone 5 中,spring-web-reactive
模組已重新命名為 spring-webflux
- 從 Spring Web Reactive API 核心的 Flux 反應式類型 中汲取靈感和簡潔性,我們較低層級的反應式 HTTP 抽象位於通用的 spring-web
模組中。 因此,我們現在有並排的 spring-webmvc
和 spring-webflux
模組,我們將其稱為 *Spring (Web)MVC* 和 *Spring WebFlux*。 如果您想知道:新模組中的頂層套件是 org.springframework.web.reactive
。
現在介紹此領域中的其他一些主要更新...
`WebClient` 是 `RestTemplate` 的反應式、非阻塞替代方案,它為 *反應式* 和 *Servlet 堆疊* 應用程式增加了價值。 它可以輕鬆處理非同步和串流案例。
在 M5 中,我們進行了重大改進,消除了使用靜態匯入來指定請求詳細資訊和執行交換的需求
WebClient webClient = WebClient.create();
Mono<Person> person = webClient.get()
.uri("http://localhost:8080/persons/42")
.accept(MediaType.APPLICATION_JSON)
.exchange()
.then(response -> response.bodyToMono(Person.class));
如果所有請求都有一個通用基本 URL,則可以預先設定一次
WebClient webClient = WebClient.create("http://localhost:8080");
Mono<Person> person = webClient.get()
.uri("/persons/{id}", 42)
.accept(MediaType.APPLICATION_JSON)
.exchange()
.then(response -> response.bodyToMono(Person.class));
也可以使用 UriBuilder
獲得程式化的控制
Mono<Person> person = webClient.get()
.uri(builder -> builder.path("/persons/{id}").build("42"))
.accept(MediaType.APPLICATION_JSON)
.exchange()
.then(response -> response.bodyToMono(Person.class));
`spring-test` 模組中的新 `WebTestClient` 構成了 Spring WebFlux 整合測試支援的基礎。 它封裝了 `WebClient` 並公開了用於整合測試的 API。 與 Spring MVC Test 中的 `MockMvc` 類似,新的測試用戶端不需要實際運行的伺服器,並且可以使用模擬請求和回應直接繫結到 WebFlux 伺服器基礎結構:````java WebTestClient client = WebTestClient .bindToController(new PersonController()) .build();
client.get().uri("/persons/42") .exchange() .expectStatus().isOk() .expectHeader().contentType(MediaType.APPLICATION_JSON_UTF8) .expectBody(Person.class).value().isEqualTo(new Person("John"));
The new test client however can also run against a live server:
````java
WebTestClient client = WebTestClient
.bindToServer().baseUrl("http://localhost:8080")
.build();
// Same test case...
串流也很容易測試,可能使用 Reactor StepVerifier
FluxExchangeResult<Person> result = client.get().uri("/persons")
.accept(TEXT_EVENT_STREAM)
.exchange()
.expectStatus().isOk()
.expectHeader().contentType(TEXT_EVENT_STREAM)
.expectBody(Person.class)
.returnResult();
StepVerifier.create(result.getResponseBody())
.expectNext(new Person("Jane"), new Person("Jason"))
.expectNextCount(3)
.consumeNextWith(p -> assertEquals("John", p.getName()))
.thenCancel()
.verify();
M5 版本新增了一個新的 `PathPatternParser` 來替代 `AntPathMatcher`,它可以使用更有效率的請求對應剖析模式表示法,並支援非常方便的 `"{*foo}" ` URI 變數語法來擷取模式結尾處的任意數量的區段。
作為第一步,新的 ParsingPathMatcher
實作已經允許將新的 PathPatternParser
輕鬆插入到 Spring MVC 和 Spring WebFlux 對應中。 作為邁向 RC1 的下一步,目標是擁有一個模式登錄檔,以便針對請求路徑的剖析表示法進行比對。
使用 Spring WebFlux 可以輕鬆支援串流:````java @GetMapping(path = "/persons", produces = "text/event-stream") Flux
但是對於以下情況應該怎麼辦
@GetMapping("/persons")
Flux<Person> getPersons() {
return this.repository.getPersons();
}
我們可以串流個別的 JSON 物件,但這不會是有效的 JSON 文件,而且除了使用伺服器發送事件或 WebSocket 之外,瀏覽器用戶端沒有其他方法可以使用串流。
預設情況下,Flux<Person>
將產生 JSON 陣列
[{"name":"Jane"},{"name":"John"},...]
非瀏覽器用戶端(例如 WebClient
)可以要求內容類型 application/stream+json
,回應將是類似於伺服器發送事件的 JSON 物件串流,但沒有額外的格式設定
{"name":"Jane"}
{"name":"John"}
...
我要感謝所有嘗試 Spring Framework 5.0 並提供回饋的人,尤其是在新的反應式功能方面。 請繼續這樣做。 與往常一樣,即使是很小的意見也可能非常寶貴,因為它們使我們從不同的角度重新審視設計選擇。
如果您本週從 DevNexus 閱讀此內容,請不要錯過 觀看令人驚嘆的 Josh Long 現場編寫反應式 Web 應用程式的機會,以及 Reactor 團隊核心成員 Simon Baslé 的 Reactor 3 演講。