日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 前端技术 > javascript >内容正文

javascript

使用SpringWebFlux的反应式Web应用程序

發(fā)布時(shí)間:2023/12/3 javascript 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用SpringWebFlux的反应式Web应用程序 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

1.反應(yīng)式編程簡(jiǎn)介

反應(yīng)式編程是為具有以下特征的應(yīng)用程序創(chuàng)造的術(shù)語(yǔ):

  • 非阻塞應(yīng)用
  • 事件驅(qū)動(dòng)和異步
  • 需要少量線程來(lái)垂直擴(kuò)展(即在JVM中)

就像面向?qū)ο蟮木幊?#xff0c;函數(shù)式編程或過(guò)程式編程一樣,反應(yīng)式編程只是另一種編程范例。 它使我們的程序成為:響應(yīng)式,彈性,彈性。

2. Spring的反應(yīng)式編程

Spring框架內(nèi)部使用Reactor為其自身提供響應(yīng)式支持。 Reactor是Reactive Streams(發(fā)布程序,在Java9中引入)的實(shí)現(xiàn)。 Reactor具有以下兩種數(shù)據(jù)類(lèi)型:

  • 助焊劑(它是一個(gè)可以發(fā)射0個(gè)或多個(gè)元素的流)
  • 單聲道(它是一個(gè)可以發(fā)出0或1個(gè)元素的流)

Spring從其API中公開(kāi)這些類(lèi)型,從而使應(yīng)用程序具有響應(yīng)性。

在Spring5中,引入了一個(gè)名為WebFlux的新模塊,該模塊支持使用以下方式創(chuàng)建反應(yīng)式Web應(yīng)用程序:HTTP(REST)和Web套接字。

Spring Web Flux支持以下兩種模型:

  • 功能模型
  • 注釋模型

在本文中,我們將探討功能模型。

下表比較了普通Spring和Web Flux:

傳統(tǒng)堆棧 反應(yīng)堆
Spring Web MVC SpringWebFlux
控制器和處理程序映射 路由器功能
Servlet API HTTP /反應(yīng)流
Servlet容器 任何支持Servlet 3.1 +,Tomcat 8.x,Jetty,Netty,UnderTow的servlet容器

3.用例

必須為員工管理系統(tǒng)創(chuàng)建一個(gè)使用Spring Web Flux的REST API,該系統(tǒng)將在員工身上公開(kāi)CRUD。

注意:項(xiàng)目的DAO層是硬編碼的。

4.所需的軟件和環(huán)境

  • Java:1.8以上
  • Maven:3.3.9或更高
  • Eclipse Luna或以上
  • Spring靴:2.0.0.M4
  • Spring Boot Starter WebFlux
  • 郵遞員測(cè)試應(yīng)用程序

5.申請(qǐng)流程

Spring5 WebFlux的功能模型是使用Spring MVC樣式注釋的替代方法。 在Spring WebFlux功能模型中,路由器和處理程序函數(shù)用于創(chuàng)建MVC應(yīng)用程序.HTTP請(qǐng)求通過(guò)路由器函數(shù)路由(替代@RequestMapping注解),請(qǐng)求通過(guò)處理程序函數(shù) (替代@Controller處理程序方法)進(jìn)行處理。

每個(gè)處理程序函數(shù)都將ServerRequest ( org.springframework.web.reactive.function.server.ServerRequest )作為參數(shù),結(jié)果將返回Mono<ServerResponse>或Flux<ServerResponse> ( org.springframework.web.reactive.function.server.ServerResponse )。

6.用例代碼和描述

pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.webflux</groupId><artifactId>Demo_Spring_MVC_Web_Flux</artifactId><version>0.0.1-SNAPSHOT</version><repositories><repository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><snapshots><enabled>true</enabled></snapshots></repository><repository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></repository></repositories><pluginRepositories><pluginRepository><id>spring-snapshots</id><name>Spring Snapshots</name><url>https://repo.spring.io/snapshot</url><snapshots><enabled>true</enabled></snapshots></pluginRepository><pluginRepository><id>spring-milestones</id><name>Spring Milestones</name><url>https://repo.spring.io/milestone</url><snapshots><enabled>false</enabled></snapshots></pluginRepository></pluginRepositories><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.0.0.M4</version><relativePath /><!-- lookup parent from repository --></parent><properties><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding><project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding><!-- Configuring Java 8 for the Project --><java.version>1.8</java.version></properties><!--Excluding Embedded tomcat to make use of the Netty Server--><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId><exclusions><exclusion><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-tomcat</artifactId></exclusion></exclusions></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-webflux</artifactId></dependency></dependencies><build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build> </project>

EmployeeDAO.java

package com.webflux.dao; import java.util.LinkedHashMap; import java.util.Map; import org.springframework.stereotype.Repository; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import com.webflux.bussiness.bean.Employee; @Repository public class EmployeeDAO {/*** Map is used to Replace the Database * */static public Map mapOfEmloyeess = new LinkedHashMap();static int count=10004;static{mapOfEmloyeess.put(10001, new Employee("Jack",10001,12345.6,1001));mapOfEmloyeess.put(10002, new Employee("Justin",10002,12355.6,1002));mapOfEmloyeess.put(10003, new Employee("Eric",10003,12445.6,1003));}/*** Returns all the Existing Employees as Flux* */public Flux getAllEmployee(){return Flux.fromStream(mapOfEmloyeess.values().stream()); }/**Get Employee details using EmployeeId .* Returns a Mono response with Data if Employee is Found* Else returns a null* */public Mono getEmployeeDetailsById(int id){Monores = null;Employee emp =mapOfEmloyeess.get(id);if(emp!=null){res=Mono.just(emp);}return res;}/**Create Employee details.* Returns a Mono response with auto-generated Id* */public Mono addEmployee(Employee employee){count++;employee.setEmployeeId(count);mapOfEmloyeess.put(count, employee);return Mono.just(count);}/**Update the Employee details,* Receives the Employee Object and returns the updated Details* as Mono * */public Mono updateEmployee (Employee employee){mapOfEmloyeess.put(employee.getEmployeeId(), employee);return Mono.just(employee);}/**Delete the Employee details,* Receives the EmployeeID and returns the deleted employee Details* as Mono * */public Mono removeEmployee (int id){Employee emp= mapOfEmloyeess.remove(id);return Mono.just(emp);} }

可以觀察到, EmployeeDAO所有方法都返回Mono或Flux Response,從而使DAO層處于活動(dòng)狀態(tài)。

EmployeeHandler.java

package com.webflux.web.handler; import static org.springframework.web.reactive.function.BodyInserters.fromObject; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.reactive.function.BodyExtractors; import org.springframework.web.reactive.function.server.ServerRequest; import org.springframework.web.reactive.function.server.ServerResponse; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import com.webflux.bussiness.bean.Employee; import com.webflux.dao.EmployeeDAO; @Controller public class EmployeeHandler {@Autowiredprivate EmployeeDAO employeeDAO;/*** Receives a ServerRequest.* Invokes the method getAllEmployee() from EmployeeDAO.* Prepares a Mono and returns the same.* */ public Mono getEmployeeDetails(ServerRequest request) {Flux res=employeeDAO.getAllEmployee(); return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON).body(res,Employee.class);}/*** Receives a ServerRequest.* Extracts the Path Variable (named id) from the Request.* Invokes the method [getEmployeeDetailsById()] from EmployeeDAO.* Verifies if the object returned in the previous step is null * then returns a Bad request with appropriate message.* Else Returns the Mono with the Employee Data.* */public Mono getEmployeeDetailByEmployeeId(ServerRequest request) {//Extracts the Path Variable id from the Requestint id =Integer.parseInt(request.pathVariable("id"));Mono employee = employeeDAO.getEmployeeDetailsById(id);Mono res= null;if(employee==null){res=ServerResponse.badRequest().body(fromObject("Please give a valid employee Id"));}else{//Converting Mono of Mono type to Monores=employee.flatMap(x->ServerResponse.ok().body(fromObject(x))); }return res;}/*** Receives a ServerRequest.* Makes use of BodyExtractors and Extracts the Employee Data as * Mono from the ServerRequest.* Invokes the method [addEmployee()] of the EmployeeDAO.* Prepares a Mono and returns the same. * */public Mono addEmployee(ServerRequest request) {Mono requestBodyMono = request.body(BodyExtractors.toMono(Employee.class));Mono mono= employeeDAO.addEmployee(requestBodyMono.block());//Converting Mono of Mono type to MonoMono res= mono.flatMap(x->ServerResponse.ok().body(fromObject("Employee Created with Id"+x))); return res;}/*** Receives a ServerRequest.* Makes use of BodyExtractors and Extracts the Employee Data as * Mono from the ServerRequest.* Finds the Employee and updates the details by invoking updateEmployee() of * EmployeeDAO. * Prepares a Mono and returns the same.* */public Mono updateEmployee(ServerRequest request) {Mono requestBodyMono = request.body(BodyExtractors.toMono(Employee.class));Employee employee = requestBodyMono.block();Mono employeeRet = employeeDAO.getEmployeeDetailsById(employee.getEmployeeId());Mono res= null;if(employeeRet==null){res=ServerResponse.badRequest().body(fromObject("Please Give valid employee details to update"));}else{Mono emp= employeeDAO.updateEmployee(employee);//Converting Mono of Mono type to Monores=emp.flatMap(x->ServerResponse.ok().body(fromObject(x)));}return res; }/*** Receives a ServerRequest.* Makes use of BodyExtractors and Extracts the Employee Data as * Mono from the ServerRequest.* Finds the Employee and deletes the details by invoking removeEmployee() of * EmployeeDAO. * Prepares a Mono and returns the same.* */public Mono deleteEmployee(ServerRequest request) {int myId = Integer.parseInt(request.pathVariable("id"));Mono res= null;if (employeeDAO.getEmployeeDetailsById(myId) == null) {res=ServerResponse.badRequest().body(fromObject("Please Give valid employee details to delete"));}else{Mono employee = employeeDAO.removeEmployee(myId);//Converting Mono of Mono type to Monores=employee.flatMap(x->ServerResponse.ok().body(fromObject(x))); }return res;} }

可以看出,Handler的所有方法都返回Mono<ServerResponse> ,從而使表示層處于響應(yīng)狀態(tài)。

注意 :事件處理程序方法應(yīng)接受ServerRequest并應(yīng)返回Mono<ServerResponse>

RouterConfiguration.java

package com.webflux.web.router.config; import static org.springframework.web.reactive.function.server.RequestPredicates.DELETE; import static org.springframework.web.reactive.function.server.RequestPredicates.GET; import static org.springframework.web.reactive.function.server.RequestPredicates.POST; import static org.springframework.web.reactive.function.server.RequestPredicates.PUT; import static org.springframework.web.reactive.function.server.RequestPredicates.accept; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.MediaType; import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.RouterFunctions; import org.springframework.web.reactive.function.server.ServerResponse; import com.webflux.web.handler.EmployeeHandler; @Configuration /*** Router is configuration class.* It links the incoming requests with appropriate HTTP methods to the * respective method of the EmployeeHandler.* Method references are used for the mapping.* */ public class RouterConfiguration{@AutowiredEmployeeHandler employeeHandler;@Beanpublic RouterFunction monoRouterFunction() {RouterFunctionrouterFunction= RouterFunctions. route(GET("/emp/controller/getDetails").and(accept(MediaType.APPLICATION_JSON)), employeeHandler::getEmployeeDetails).andRoute(GET("/emp/controller/getDetailsById/{id}").and(accept(MediaType.APPLICATION_JSON)), employeeHandler::getEmployeeDetailByEmployeeId).andRoute(POST("/emp/controller/addEmp").and(accept(MediaType.APPLICATION_JSON)), employeeHandler::addEmployee).andRoute(PUT("/emp/controller/updateEmp").and(accept(MediaType.APPLICATION_JSON)), employeeHandler::updateEmployee).andRoute(DELETE("/emp/controller/deleteEmp/{id}").and(accept(MediaType.APPLICATION_JSON)), employeeHandler::deleteEmployee);return routerFunction;} }

ApplicationBootUp.java

package com.webflux; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class ApplicationBootUp {public static void main(String[] args) {SpringApplication.run(ApplicationBootUp.class);}}

在application.properties內(nèi)部,僅提及服務(wù)器端口: server.port=8090 。

可以使用以下命令部署應(yīng)用程序: clean install spring-boot:run并使用postman client進(jìn)行測(cè)試。

7.參考:

  • https://docs.spring.io/spring/docs/5.0.0.BUILD-SNAPSHOT/spring-framework-reference/html/web-reactive.html
  • http://www.baeldung.com/reactor-core
  • http://www.baeldung.com/spring-5-functional-web

8.下載Eclipse項(xiàng)目

下載
您可以在此處下載此示例的完整源代碼: SpringWebFlux

翻譯自: https://www.javacodegeeks.com/2018/01/reactive-web-applications-using-springwebflux.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來(lái)咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的使用SpringWebFlux的反应式Web应用程序的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。