SpringBoot2使用WebFlux函數(shù)式編程的方法
本文只是簡(jiǎn)單使用SpringBoot2使用WebFlux的函數(shù)式編程簡(jiǎn)單使用,后續(xù)會(huì)繼續(xù)寫關(guān)于Webflux相關(guān)的文章。
最近一直在研究WebFlux,后續(xù)會(huì)陸續(xù)出一些相關(guān)的文章。
首先看一下Srping官網(wǎng)上的一張圖,對(duì)比一下SpringMvc和Spring WebFlux,如圖:

在查看一下WebFlux的官方文檔:https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html,WebFlux提供了函數(shù)式編程,本文簡(jiǎn)單介紹一下WebFlux函數(shù)式編程簡(jiǎn)單使用。
新建項(xiàng)目
創(chuàng)建一個(gè)項(xiàng)目,pom文件中引入webflux依賴,完整pom文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<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.dalaoyang</groupId>
<artifactId>springboot2_webflux</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>springboot2_webflux</name>
<description>springboot2_webflux</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</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>
首先試試引入WebFlux依賴之后,SpringMvc方式是否還能使用,新建一個(gè)HelloController,完整代碼如下,執(zhí)行后發(fā)現(xiàn),是可以正常執(zhí)行訪問的,這其實(shí)就是我們所說(shuō)的注解式編程。
package com.dalaoyang.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author dalaoyang
* @project springboot_learn
* @package com.dalaoyang.controller
* @email yangyang@dalaoyang.cn
* @date 2018/7/30
*/
@RestController
public class HelloController {
@GetMapping("hello")
public String Hello(){
return "Hello this is SpringWebFlux";
}
}
結(jié)果如圖:

接下來(lái)使用函數(shù)式編程,首先查閱一下官方文檔,如圖:

我們需要?jiǎng)?chuàng)建一個(gè)HandlerFunction返回值為Mono,新建一個(gè)HiHandler,里面寫一個(gè)方法Hi,完整代碼如下:
package com.dalaoyang.handler;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.BodyInserters;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
/**
* @author dalaoyang
* @project springboot_learn
* @package com.dalaoyang.handler
* @email yangyang@dalaoyang.cn
* @date 2018/7/30
*/
@Component
public class HiHandler {
public Mono<ServerResponse> Hi(ServerRequest request) {
return ServerResponse.ok().contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromObject("Hi , this is SpringWebFlux"));
}
}
其中ServerResponse是相應(yīng)的封裝對(duì)象,下面是它的源碼,其中包含了響應(yīng)狀態(tài),響應(yīng)頭等等,代碼如下:
package org.springframework.web.reactive.function.server;
import java.net.URI;
import java.time.ZonedDateTime;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import java.util.function.Consumer;
import org.reactivestreams.Publisher;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.CacheControl;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseCookie;
import org.springframework.http.codec.HttpMessageWriter;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.util.MultiValueMap;
import org.springframework.web.reactive.function.BodyInserter;
import org.springframework.web.reactive.result.view.ViewResolver;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
public interface ServerResponse {
HttpStatus statusCode();
HttpHeaders headers();
MultiValueMap<String, ResponseCookie> cookies();
Mono<Void> writeTo(ServerWebExchange var1, ServerResponse.Context var2);
static ServerResponse.BodyBuilder from(ServerResponse other) {
return new DefaultServerResponseBuilder(other);
}
static ServerResponse.BodyBuilder status(HttpStatus status) {
return new DefaultServerResponseBuilder(status);
}
static ServerResponse.BodyBuilder status(int status) {
return new DefaultServerResponseBuilder(status);
}
static ServerResponse.BodyBuilder ok() {
return status(HttpStatus.OK);
}
static ServerResponse.BodyBuilder created(URI location) {
ServerResponse.BodyBuilder builder = status(HttpStatus.CREATED);
return (ServerResponse.BodyBuilder)builder.location(location);
}
static ServerResponse.BodyBuilder accepted() {
return status(HttpStatus.ACCEPTED);
}
static ServerResponse.HeadersBuilder<?> noContent() {
return status(HttpStatus.NO_CONTENT);
}
static ServerResponse.BodyBuilder seeOther(URI location) {
ServerResponse.BodyBuilder builder = status(HttpStatus.SEE_OTHER);
return (ServerResponse.BodyBuilder)builder.location(location);
}
static ServerResponse.BodyBuilder temporaryRedirect(URI location) {
ServerResponse.BodyBuilder builder = status(HttpStatus.TEMPORARY_REDIRECT);
return (ServerResponse.BodyBuilder)builder.location(location);
}
static ServerResponse.BodyBuilder permanentRedirect(URI location) {
ServerResponse.BodyBuilder builder = status(HttpStatus.PERMANENT_REDIRECT);
return (ServerResponse.BodyBuilder)builder.location(location);
}
static ServerResponse.BodyBuilder badRequest() {
return status(HttpStatus.BAD_REQUEST);
}
static ServerResponse.HeadersBuilder<?> notFound() {
return status(HttpStatus.NOT_FOUND);
}
static ServerResponse.BodyBuilder unprocessableEntity() {
return status(HttpStatus.UNPROCESSABLE_ENTITY);
}
public interface Context {
List<HttpMessageWriter<?>> messageWriters();
List<ViewResolver> viewResolvers();
}
public interface BodyBuilder extends ServerResponse.HeadersBuilder<ServerResponse.BodyBuilder> {
ServerResponse.BodyBuilder contentLength(long var1);
ServerResponse.BodyBuilder contentType(MediaType var1);
ServerResponse.BodyBuilder hint(String var1, Object var2);
<T, P extends Publisher<T>> Mono<ServerResponse> body(P var1, Class<T> var2);
<T, P extends Publisher<T>> Mono<ServerResponse> body(P var1, ParameterizedTypeReference<T> var2);
Mono<ServerResponse> syncBody(Object var1);
Mono<ServerResponse> body(BodyInserter<?, ? super ServerHttpResponse> var1);
Mono<ServerResponse> render(String var1, Object... var2);
Mono<ServerResponse> render(String var1, Map<String, ?> var2);
}
public interface HeadersBuilder<B extends ServerResponse.HeadersBuilder<B>> {
B header(String var1, String... var2);
B headers(Consumer<HttpHeaders> var1);
B cookie(ResponseCookie var1);
B cookies(Consumer<MultiValueMap<String, ResponseCookie>> var1);
B allow(HttpMethod... var1);
B allow(Set<HttpMethod> var1);
B eTag(String var1);
B lastModified(ZonedDateTime var1);
B location(URI var1);
B cacheControl(CacheControl var1);
B varyBy(String... var1);
Mono<ServerResponse> build();
Mono<ServerResponse> build(Publisher<Void> var1);
Mono<ServerResponse> build(BiFunction<ServerWebExchange, ServerResponse.Context, Mono<Void>> var1);
}
}
在回過頭了看上面官方文檔的圖片,還需要配置一個(gè)路由來(lái)類似@RequestMapping的功能,通過RouterFunctions.route(RequestPredicate, HandlerFunction)提供了一個(gè)路由器函數(shù)默認(rèn)實(shí)現(xiàn),新建一個(gè)HiRouter,代碼如下:
package com.dalaoyang.router;
import com.dalaoyang.handler.HiHandler;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.MediaType;
import org.springframework.web.reactive.function.server.RequestPredicates;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.RouterFunctions;
import org.springframework.web.reactive.function.server.ServerResponse;
/**
* @author dalaoyang
* @project springboot_learn
* @package com.dalaoyang.router
* @email yangyang@dalaoyang.cn
* @date 2018/7/30
*/
@Configuration
public class HiRouter {
@Bean
public RouterFunction<ServerResponse> routeCity(HiHandler hiHandler) {
return RouterFunctions
.route(RequestPredicates.GET("/hi")
.and(RequestPredicates.accept(MediaType.APPLICATION_JSON)),
hiHandler::Hi);
}
}
啟動(dòng)項(xiàng)目,通過控制臺(tái)可以看到,兩種方式的映射都被打印出來(lái)了,如圖所示:

在瀏覽器訪問,http://localhost:8080/hi,結(jié)果如圖所示:

源碼下載 :大老楊碼云
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- SpringBoot 使用@WebMvcTest測(cè)試MVC Web Controller
- SpringBoot中通過實(shí)現(xiàn)WebMvcConfigurer參數(shù)校驗(yàn)的方法示例
- springboot webflux 過濾器(使用RouterFunction實(shí)現(xiàn))
- SpringBoot之webflux全面解析
- SpringBoot?Webflux創(chuàng)建TCP/UDP?server并使用handler解析數(shù)據(jù)
- 關(guān)于springboot響應(yīng)式編程整合webFlux的問題
- Springboot WebFlux集成Spring Security實(shí)現(xiàn)JWT認(rèn)證的示例
- SpringBoot深入分析webmvc和webflux的區(qū)別
相關(guān)文章
Java及nginx實(shí)現(xiàn)文件權(quán)限控制代碼實(shí)例
這篇文章主要介紹了Java及nginx實(shí)現(xiàn)文件權(quán)限控制代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
SpringBoot?ApplicationContext接口深入分析
ApplicationContext是Spring應(yīng)用程序中的中央接口,由于繼承了多個(gè)組件,使得ApplicationContext擁有了許多Spring的核心功能,如獲取bean組件,注冊(cè)監(jiān)聽事件,加載資源文件等2022-11-11
Spring使用aop切面編程時(shí)要給那些類加注解的實(shí)例
在使用切面編程時(shí),通常需要為以下類或組件添加注解來(lái)標(biāo)識(shí)它們,以便 Spring 或其他切面框架能夠正確識(shí)別和處理它們,這篇文章主要介紹了Spring使用aop切面編程時(shí)要給那些類加注解,需要的朋友可以參考下2023-11-11
JAVA為什么要使用封裝及如何封裝經(jīng)典實(shí)例
這篇文章主要給大家介紹了關(guān)于JAVA為什么要使用封裝及如何封裝的相關(guān)資料,封裝就是將屬性私有化,提供公有的方法訪問私有屬性,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-10-10
淺析SpringMVC中的適配器HandlerAdapter
這篇文章主要介紹了SpringMVC中的適配器HandlerAdapter的相關(guān)資料,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01
Kotlin基礎(chǔ)教程之dataclass,objectclass,use函數(shù),類擴(kuò)展,socket
這篇文章主要介紹了Kotlin基礎(chǔ)教程之dataclass,objectclass,use函數(shù),類擴(kuò)展,socket的相關(guān)資料,需要的朋友可以參考下2017-05-05
Java WebService 簡(jiǎn)單實(shí)例(附實(shí)例代碼)
本篇文章主要介紹了Java WebService 簡(jiǎn)單實(shí)例(附實(shí)例代碼), Web Service 是一種新的web應(yīng)用程序分支,他們是自包含、自描述、模塊化的應(yīng)用,可以發(fā)布、定位、通過web調(diào)用。有興趣的可以了解一下2017-01-01
SpringBoot?實(shí)現(xiàn)動(dòng)態(tài)添加定時(shí)任務(wù)功能
這篇文章主要介紹了SpringBoot?動(dòng)態(tài)添加定時(shí)任務(wù),本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-02-02
微信小程序完整項(xiàng)目實(shí)戰(zhàn)記錄(前端+SpringBoot后端)
隨著微信小程序的流行,越來(lái)越多的開發(fā)者開始涉足小程序開發(fā),下面這篇文章主要給大家介紹了關(guān)于微信小程序完整項(xiàng)目實(shí)戰(zhàn)的相關(guān)資料,項(xiàng)目包括前端+SpringBoot后端,需要的朋友可以參考下2024-09-09

