成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring WebFlux入門實(shí)例并整合數(shù)據(jù)庫實(shí)現(xiàn)基本的增刪改查

開發(fā) 前端
Spring Web模塊包含了Spring WebFlux的基礎(chǔ),包括HTTP抽象、支持服務(wù)器的反應(yīng)流適配器、編解碼器和與Servlet API相媲美的核心WebHandler-API,但是具有非阻塞契約。

[[429958]]

環(huán)境:Springboot2.4.11

概述

為什么創(chuàng)建了SpringWebFlux?

部分答案是需要一個非阻塞web堆棧來處理具有少量線程的并發(fā)性,并使用較少的硬件資源進(jìn)行擴(kuò)展。Servlet 3.1確實(shí)為非阻塞I/O提供了一個API。但是,使用它會導(dǎo)致Servlet API的其他部分出現(xiàn)偏差。這是一個新的公共API在任何非阻塞運(yùn)行時作為基礎(chǔ)的動機(jī)。這一點(diǎn)很重要,因?yàn)榉?wù)器(如Netty)在異步、非阻塞空間中建立良好。

答案的另一部分是函數(shù)式編程。正如Java 5中添加注釋創(chuàng)造了機(jī)會(如帶注釋的REST控制器或單元測試),Java 8中添加lambda表達(dá)式也為Java中的函數(shù)API創(chuàng)造了機(jī)會。這對于允許異步邏輯的聲明性組合的非阻塞應(yīng)用程序和延續(xù)式API(CompletableFuture和ReactiveX推廣)是一個福音。在編程模型級別,Java8支持SpringWebFlux提供功能性web端點(diǎn)和帶注釋的控制器。

什么是反應(yīng)式編程?

“反應(yīng)式”指的是圍繞對變化作出反應(yīng)而構(gòu)建的編程模型 — 響應(yīng)I/O事件的網(wǎng)絡(luò)組件、響應(yīng)鼠標(biāo)事件的UI控制器以及其他組件。非阻塞是反應(yīng)性的,因?yàn)槲覀儸F(xiàn)在不是被阻塞,而是在操作完成或數(shù)據(jù)可用時對通知作出反應(yīng)。還有另一個重要的機(jī)制,我們Spring團(tuán)隊(duì)將其與“反應(yīng)性”聯(lián)系起來,那就是無阻塞背壓。在同步命令式代碼中,阻塞調(diào)用作為一種自然形式的背壓,迫使調(diào)用方等待。在非阻塞代碼中,控制事件的速率變得非常重要,以便快速生產(chǎn)者不會壓倒其目的地。

Reactive Streams 是一個小規(guī)范(在Java9中也采用),它定義了具有背壓的異步組件之間的交互。例如,數(shù)據(jù)存儲庫(充當(dāng)發(fā)布者)可以生成HTTP服務(wù)器(充當(dāng)訂戶)可以寫入響應(yīng)的數(shù)據(jù)。反應(yīng)流的主要目的是讓訂閱者控制發(fā)布者生成數(shù)據(jù)的速度。

Reactive Streams 在互操作性方面起著重要作用。它對庫和基礎(chǔ)結(jié)構(gòu)組件很感興趣,但作為應(yīng)用程序API不太有用,因?yàn)樗募墑e太低。應(yīng)用程序需要更高級別、更豐富、功能更強(qiáng)大的API來組成異步邏輯 — 與Java8流API類似,但不僅僅針對集合。這就是反應(yīng)式庫所扮演的角色。

Reactor是Spring WebFlux的首選反應(yīng)庫。它提供了Mono和Flux API類型,通過與ReactiveX操作符詞匯表對齊的一組豐富的操作符來處理0..1(Mono)和0..N(Flux)的數(shù)據(jù)序列。反應(yīng)器是一個反應(yīng)流庫,因此,其所有操作員都支持非阻塞背壓。Reactor非常關(guān)注服務(wù)器端Java。它是與Spring密切合作開發(fā)的。

WebFlux需要Reactor作為核心依賴項(xiàng),但它可以通過反應(yīng)流與其他反應(yīng)庫進(jìn)行互操作。作為一般規(guī)則,WebFlux API接受普通發(fā)布服務(wù)器作為輸入,在內(nèi)部將其調(diào)整為反應(yīng)器類型,使用該類型,并返回Flux或Mono作為輸出。

編程模型

Spring Web模塊包含了Spring WebFlux的基礎(chǔ),包括HTTP抽象、支持服務(wù)器的反應(yīng)流適配器、編解碼器和與Servlet API相媲美的核心WebHandler-API,但是具有非阻塞契約。

在此基礎(chǔ)上,Spring WebFlux提供了兩種編程模型的選擇:

  1. Annotated Controllers:與SpringMVC一致,并基于SpringWeb模塊中相同的注釋。SpringMVC和WebFlux控制器都支持反應(yīng)式(Reactor和RxJava)返回類型,因此很難區(qū)分它們。一個顯著的區(qū)別是WebFlux還支持反應(yīng)式@RequestBody參數(shù)。
  2. Functional Endpoints: 基于Lambda的輕量級功能性編程模型。您可以將其視為一個小型庫或一組應(yīng)用程序可用于路由和處理請求的實(shí)用程序。帶注釋控制器的最大區(qū)別在于,應(yīng)用程序從頭到尾負(fù)責(zé)請求處理,而不是通過注釋聲明意圖并被回調(diào)。

適用性

Spring MVC or WebFlux如何選擇?

它們可以并排使用,并且來自各方的反饋對雙方都有利。下圖顯示了兩者之間的關(guān)系、它們的共同點(diǎn)以及各自唯一支持的內(nèi)容:

Spring WebFlux入門實(shí)例并整合數(shù)據(jù)庫實(shí)現(xiàn)基本的增刪改查

我們建議你考慮以下幾點(diǎn):

  • 如果你有一個運(yùn)行良好的SpringMVC應(yīng)用程序,則無需進(jìn)行更改。命令式編程是編寫、理解和調(diào)試代碼的最簡單方法。您可以選擇最多的庫,因?yàn)閺臍v史上看,大多數(shù)庫都是阻塞的。
  • 如果你已經(jīng)在購買非阻塞web堆棧,Spring WebFlux提供了與此領(lǐng)域其他產(chǎn)品相同的執(zhí)行模型優(yōu)勢,還提供了服務(wù)器選擇(Netty、Tomcat、Jetty、Undertow和Servlet 3.1+容器)、編程模型選擇(annotated controllers and functional web endpoints),以及可選擇的反應(yīng)庫(Reactor、RxJava或其他)。
  • 如果你對用于Java8 Lambdas或Kotlin的輕量級功能性web框架感興趣,可以使用SpringWebFlux功能性web端點(diǎn)。對于需求不太復(fù)雜的小型應(yīng)用程序或微服務(wù)來說,這也是一個不錯的選擇,因?yàn)樗鼈兛梢詮母叩耐该鞫群涂刂浦蝎@益。
  • 在微服務(wù)體系結(jié)構(gòu)中,可以混合使用具有SpringMVC或SpringWebFlux控制器或SpringWebFlux功能端點(diǎn)的應(yīng)用程序。在兩個框架中都支持相同的基于注釋的編程模型,這使得重用知識更加容易,同時也為正確的工作選擇了正確的工具。
  • 評估應(yīng)用程序的一種簡單方法是檢查其依賴性。如果你有塊持久性API(JPA、JDBC)或網(wǎng)絡(luò)API可供使用,SpringMVC至少是通用體系結(jié)構(gòu)的最佳選擇。對于Reactor和RxJava來說,在單獨(dú)的線程上執(zhí)行阻塞調(diào)用在技術(shù)上是可行的,但是你不會充分利用非阻塞web堆棧。
  • 如果你有一個SpringMVC應(yīng)用程序,可以調(diào)用遠(yuǎn)程服務(wù),請嘗試使用反應(yīng)式WebClient。你可以直接從SpringMVC控制器方法返回反應(yīng)類型(Reactor、RxJava或其他)。每次調(diào)用的延遲或調(diào)用之間的相互依賴性越大,好處就越顯著。SpringMVC控制器也可以調(diào)用其他反應(yīng)組件。
  • 如果你有一個龐大的團(tuán)隊(duì),請記住,在向非阻塞、函數(shù)式和聲明式編程轉(zhuǎn)變的過程中,學(xué)習(xí)曲線很陡峭。在沒有完全轉(zhuǎn)換的情況下啟動的一種實(shí)用方法是使用反應(yīng)式WebClient。除此之外,從小事做起,衡量效益。我們預(yù)計,對于廣泛的應(yīng)用,這種轉(zhuǎn)變是不必要的。如果您不確定要尋找哪些好處,請從了解非阻塞I/O的工作原理(例如,單線程N(yùn)ode.js上的并發(fā))及其效果開始。

應(yīng)用服務(wù)

Spring WebFlux在Tomcat、Jetty、Servlet3.1+容器以及Netty和Undertow等非Servlet運(yùn)行時上受支持。所有服務(wù)器都適用于低級別的通用API,以便跨服務(wù)器支持更高級別的編程模型。

Spring WebFlux沒有啟動或停止服務(wù)器的內(nèi)置支持。然而,從Spring配置和WebFlux基礎(chǔ)設(shè)施組裝應(yīng)用程序并用幾行代碼運(yùn)行它是很容易的。

Spring Boot有一個WebFlux啟動器,可以自動執(zhí)行這些步驟。默認(rèn)情況下,初學(xué)者使用Netty,但通過更改Maven或Gradle依賴項(xiàng),可以很容易地切換到Tomcat、Jetty或Undertow。springboot默認(rèn)為Netty,因?yàn)樗鼜V泛地用于異步、無阻塞,并允許客戶端和服務(wù)器共享資源。

Tomcat和Jetty可以與Spring MVC和WebFlux一起使用。但是,請記住,它們的使用方式是非常不同的。SpringMVC依賴于Servlet阻塞I/O,并允許應(yīng)用程序在需要時直接使用Servlet API。Spring WebFlux依賴于Servlet3.1非阻塞I/O,并在低級適配器后面使用ServletAPI。它不暴露直接使用。

對于Undertow,Spring WebFlux直接使用Undertow API,而不使用ServletAPI。

性能

性能有許多特點(diǎn)和意義。響應(yīng)式和非阻塞通常不會使應(yīng)用程序運(yùn)行得更快。在某些情況下,它們可以(例如,如果使用WebClient并行運(yùn)行遠(yuǎn)程調(diào)用)。總的來說,它需要更多的工作來完成非阻塞方式的事情,這可以稍微增加所需的處理時間。

反應(yīng)式和非阻塞的主要預(yù)期好處是能夠用少量固定數(shù)量的線程和更少的內(nèi)存進(jìn)行擴(kuò)展。這使得應(yīng)用程序在負(fù)載下更具彈性,因?yàn)樗鼈円愿深A(yù)測的方式擴(kuò)展。然而,為了觀察這些好處,你需要有一些延遲(包括緩慢和不可預(yù)測的網(wǎng)絡(luò)I/O混合)。這就是反應(yīng)堆棧開始顯示其優(yōu)勢的地方,而差異可能是巨大的。

線程模型

在SpringMVC(以及一般的servlet應(yīng)用程序)中,假定應(yīng)用程序可以阻止當(dāng)前線程(例如,遠(yuǎn)程調(diào)用)。由于這個原因,servlet容器使用一個大的線程池來吸收請求處理期間的潛在阻塞。

在Spring WebFlux(以及一般的非阻塞服務(wù)器)中,假定應(yīng)用程序不阻塞。因此,非阻塞服務(wù)器使用一個小的、固定大小的線程池(事件循環(huán)工作者)來處理請求。

  • 調(diào)用阻塞API

如果你確實(shí)需要使用阻塞庫怎么辦?Reactor和RxJava都提供publishOn操作符,以便在不同的線程上繼續(xù)處理。這意味著有一個容易逃生的艙口。但是,請記住,阻塞API并不適合此并發(fā)模型。

  • 易變狀態(tài)

在Reactor和RxJava中,通過操作符聲明邏輯。在運(yùn)行時,會形成一個反應(yīng)式管道,在該管道中,數(shù)據(jù)會在不同的階段按順序處理。這樣做的一個關(guān)鍵好處是,它使應(yīng)用程序不必保護(hù)可變狀態(tài),因?yàn)樵摴艿乐械膽?yīng)用程序代碼永遠(yuǎn)不會被并發(fā)調(diào)用。

  • 線程模型

在運(yùn)行Spring WebFlux的服務(wù)器上,你希望看到哪些線程?

在“普通”Spring WebFlux服務(wù)器上(例如,沒有數(shù)據(jù)訪問或其他可選依賴項(xiàng)),您可以期望服務(wù)器有一個線程,其他幾個線程用于請求處理(通常與CPU核數(shù)相同)。然而,Servlet容器可以從更多線程開始(例如,Tomcat上的10個線程),以支持Servlet(阻塞)I/O和Servlet 3.1(非阻塞)I/O使用。

反應(yīng)式WebClient以事件循環(huán)方式運(yùn)行。因此,您可以看到與此相關(guān)的少量固定數(shù)量的處理線程(例如,reactor http nio-帶有reactor Netty連接器)。但是,如果Reactor Netty同時用于客戶端和服務(wù)器,則默認(rèn)情況下,這兩個服務(wù)器共享事件循環(huán)資源。

Reactor和RxJava提供了線程池抽象,稱為調(diào)度程序,與publishOn操作符一起使用,publishOn操作符用于將處理切換到不同的線程池。調(diào)度程序的名稱表示特定的并發(fā)策略 — 例如,“并行”(用于CPU綁定的、線程數(shù)量有限的工作)或“彈性”(用于I/O綁定的、線程數(shù)量較多的工作)。如果你看到這樣的線程,則意味著某些代碼正在使用特定的線程池調(diào)度程序策略。

數(shù)據(jù)訪問庫和其他第三方依賴項(xiàng)也可以創(chuàng)建和使用自己的線程。

引入依賴

  1. <dependency> 
  2.   <groupId>org.springframework.boot</groupId> 
  3.   <artifactId>spring-boot-starter-webflux</artifactId> 
  4. </dependency> 
  5. <!--R2DBC是基于Reactive Streams標(biāo)準(zhǔn)來設(shè)計的。通過使用R2DBC,你可以使用reactive API來操作數(shù)據(jù)。同時R2DBC只是一個開放的標(biāo)準(zhǔn),而各個具體的數(shù)據(jù)庫連接實(shí)現(xiàn),需要實(shí)現(xiàn)這個標(biāo)準(zhǔn)。--> 
  6. <dependency> 
  7.   <groupId>org.springframework.boot</groupId> 
  8.   <artifactId>spring-boot-starter-data-r2dbc</artifactId> 
  9. </dependency> 
  10. <!--響應(yīng)式編程傳統(tǒng)的jdbc操作是阻塞式的,所以不能再用以前的mysql驅(qū)動了--> 
  11. <dependency> 
  12.   <groupId>dev.miku</groupId> 
  13.   <artifactId>r2dbc-mysql</artifactId> 
  14. </dependency> 

相關(guān)配置

  1. spring: 
  2.   r2dbc: 
  3.     #連接數(shù)據(jù)庫的url,前綴不再是jdbc而是換成r2dbc 
  4.     #這里可以配置連接池相關(guān)的其它屬性,這里為了簡潔不配置 
  5.     url: r2dbc:mysql://localhost:3306/testjpa 
  6.     username: root 
  7.     password: 123123 

PO定義

  1. @Table(value = "reactive_users"
  2. public class Users implements Serializable { 
  3.   @Id 
  4.   private Long id ; 
  5.   private Integer age ; 
  6.   private String name ; 

DAO層定義

  1. // 在使用JPA時經(jīng)常用到的是JpaRepository等;在反應(yīng)式編程中不能在使用了,只能用如下的接口 
  2. public interface UsersRepository extends ReactiveCrudRepository<Users, Long>, ReactiveSortingRepository<Users, Long>{ 
  3.   // 這里的方法名定義還是與使用data-jpa時一樣的定義   
  4.   public Mono<Users> findByName(String name) ; 

Service層定義

  1. @Service 
  2. public class UsersService { 
  3.  
  4.   @Resource 
  5.   private UsersRepository usersRepository ; 
  6.      
  7.   @Transactional 
  8.   public Mono<Users> save(Users users) { 
  9.     return usersRepository.save(users) ; 
  10.   } 
  11.      
  12.   public Mono<Users> getUsers(Long id) { 
  13.     return usersRepository.findById(id) ; 
  14.   } 
  15.      
  16.   public Flux<Users> list() { 
  17.     return usersRepository.findAll() ; 
  18.   } 
  19.      
  20.   public Mono<Users> getUsersByName(String name) { 
  21.     return usersRepository.findByName(name) ; 
  22.   } 
  23.      

Service中定義了CURD操作。

Controller接口定義

  1. @RestController 
  2. @RequestMapping("/users"
  3. public class UsersController { 
  4.      
  5.   @Resource 
  6.   private UsersService usersService ; 
  7.      
  8.   @PostMapping("/save"
  9.   public Mono<Long> save(@RequestBody Users user) { 
  10.     Mono<Users> res = usersService.save(user) ; 
  11.     return res.flatMap(new Function<Users, Mono<Long>>() { 
  12.       @Override 
  13.       public Mono<Long> apply(Users t) { 
  14.         return Mono.just(t.getId()) ; 
  15.       } 
  16.     }) ; 
  17.   } 
  18.      
  19.   @GetMapping("/{id}"
  20.   public Mono<Users> getUsers(@PathVariable("id") Long id) { 
  21.     return usersService.getUsers(id) ; 
  22.   } 
  23.      
  24.   @GetMapping("/lists"
  25.   public Flux<Users> list() { 
  26.     return usersService.list() ; 
  27.   } 
  28.      
  29.   @GetMapping("/name"
  30.   public Mono<Users> name(String name) { 
  31.     return usersService.getUsersByName(name) ; 
  32.   } 
  33.      

Controller的定義還是與傳統(tǒng)的定義方式差不多,只是返回值要么是Mono(單一值),要么是Flux(集合)對象。

責(zé)任編輯:姜華 來源: 今日頭條
相關(guān)推薦

2019-11-07 15:39:36

數(shù)據(jù)庫MySQL文章

2024-09-02 09:26:28

2012-04-12 09:23:15

達(dá)夢數(shù)據(jù)庫

2009-11-13 15:54:26

ADO.NET數(shù)據(jù)庫操

2024-08-29 08:58:30

JPA編寫數(shù)據(jù)操

2012-04-19 10:06:16

ibmdw

2023-09-21 08:01:27

SpringR2DBC實(shí)現(xiàn)數(shù)據(jù)庫

2011-09-02 14:18:53

OracleBULK COLLECFORALL

2022-03-29 07:32:38

R2DBC數(shù)據(jù)庫反應(yīng)式

2010-08-31 14:24:25

DB2聯(lián)合數(shù)據(jù)庫

2016-10-13 19:16:28

Python編程語言mysql

2019-10-12 16:15:13

MySQL數(shù)據(jù)庫多實(shí)例

2023-02-27 07:37:56

Curl操作SQL

2023-06-08 08:13:43

2011-08-12 11:04:47

Oracle數(shù)據(jù)庫增刪集合元素Java

2024-11-18 00:22:34

2020-12-22 08:41:21

GolangPostgreSQL數(shù)據(jù)庫

2020-05-28 16:50:59

源碼分析 MybatisJava

2020-10-29 08:39:45

JSONJava對象

2010-06-09 17:36:45

MySQL數(shù)據(jù)庫同步
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號

主站蜘蛛池模板: 亚洲iv一区二区三区 | 亚洲一区二区视频 | 色成人免费网站 | 中文在线一区 | 黄网站免费在线观看 | 激情六月天| 粉嫩一区二区三区国产精品 | 国产一区二区视频免费在线观看 | 久色视频在线观看 | 日韩一二区 | 日韩一区二区视频 | 精品少妇一区二区三区在线播放 | 三级国产三级在线 | 日韩欧美精品一区 | 啪一啪| 日韩在线免费视频 | 欧美一区二区三区在线播放 | 日本福利片 | 久久99精品久久久久久琪琪 | 久久久成人免费一区二区 | 性做久久久久久免费观看欧美 | 亚洲国产精品一区二区第一页 | 国产九九九九 | 国产精品久久久久免费 | 亚洲第一天堂 | 亚洲精选一区 | 欧美日韩精品亚洲 | gogo肉体亚洲高清在线视 | 黄a在线观看| 亚洲日韩中文字幕一区 | 亚洲一区二区黄 | 天天干亚洲 | 中文字幕91| 狠狠久久综合 | 国产一区二区三区www | 亚洲精品国产成人 | 欧美寡妇偷汉性猛交 | 精品欧美一区二区精品久久 | 国产精品激情 | 久久久久国产一区二区三区 | 日韩精品在线视频 |