SpringBoot WebFlux响应式编程
SpringBoot WebFlux响应式编程
一、简介
Spring WebFlux是Spring Framework 5.0中引入的新的反应式Web框架。 与Spring MVC不同,它不需要Servlet API,完全异步和非阻塞, 并通过Reactor项目实现Reactive Streams规范。 并且可以在诸如Netty,Undertow和Servlet 3.1+容器的服务器上运行。
 Flux 和 Mono 是 Reactor 中的两个基本概念。Flux 表示的是包含 0 到 N 个元素的异步序列。 在该序列中可以包含三种不同类型的消息通知:正常的包含元素的消息、序列结束的消息和序列出错的消息。 当消息通知产生时,订阅者中对应的方法 onNext(), onComplete()和 onError()会被调用。Mono 表示的是包含 0 或者 1 个元素的异步序列。 该序列中同样可以包含与 Flux 相同的三种类型的消息通知。Flux 和 Mono 之间可以进行转换。 对一个 Flux 序列进行计数操作,得到的结果是一个 Mono对象。把两个 Mono 序列合并在一起,得到的是一个 Flux 对象。
二、Flux和Mono
1)简单业务而言:和其他普通对象差别不大,复杂请求业务,就可以提升性能
 2)通俗理解:
 Mono 表示的是包含 0 或者 1 个元素的异步序列
 mono->单一对象 User redis->用户ID-》唯一的用户Mono
Flux 表示的是包含 0 到 N 个元素的异步序列
 flux->数组列表对象 List redis->男性用户->Flux
 Flux 和 Mono 之间可以进行转换
三 Spring WebFlux 两种风格
1. 基于注解
@RestController 
@RequestMapping("/ users")
public  class MyRestController {
	@GetMapping("/ {user}")
	 public Mono <User> getUser( @PathVariable Long user){
		 // ...
	}
	
	@GetMapping("/ {user} / customers")
	 public Flux <Customer> getUserCustomers( @PathVariable Long user){
		 // ...
	}
	
	@DeleteMapping("/ {user}")
	 public Mono <User> deleteUser( @PathVariable Long user){
		 // ...
	}
}
  
 - 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
2. 基于功能
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.reactive.function.server.RouterFunction;
import org.springframework.web.reactive.function.server.ServerResponse;
import static org.springframework.http.MediaType.APPLICATION_JSON;
import static org.springframework.web.reactive.function.server.RequestPredicates.*;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
@Configuration
public class RoutingConfiguration {
    @Bean
    public RouterFunction<ServerResponse> monoRouterFunction(UserHandler userHandler) {
        return route(GET("/{user}").and(accept(APPLICATION_JSON)),userHandler::getUser)
                .andRoute(GET("/{user}/customers").and(accept(APPLICATION_JSON)), userHandler::getUserCustomers)
                .andRoute(DELETE("/ {user}").and(accept(APPLICATION_JSON)), userHandler::deleteUser);
    }
}
  
 - 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
import org.springframework.stereotype.Component;
import org.springframework.web.reactive.function.server.ServerRequest;
import org.springframework.web.reactive.function.server.ServerResponse;
import reactor.core.publisher.Mono;
@Component
public class UserHandler {
	public Mono<ServerResponse> getUser(ServerRequest request){
		 // ...
	}
	
	public Mono <ServerResponse> getUserCustomers(ServerRequest request){
		 // ...
	}
	
	public Mono <ServerResponse> deleteUser(ServerRequest  request){
		 // ...
	}
}
  
 - 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
注意点
Spring WebFlux应用程序不严格依赖于Servlet API,因此它们不能作为war文件部署,也不能使用src/main/webapp目录
可以整合多个模板引擎
 除了REST Web服务外,您还可以使用Spring WebFlux提供动态HTML内容。Spring WebFlux支持各种模板技术,包括Thymeleaf,FreeMarker
三、 SpringBoot简单使用
1. pom
如果有spring-boot-starter-web去掉换成下面依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
  
 - 1
- 2
- 3
- 4
2. 使用
@RestController
public class TestFluxController {
    @GetMapping("/GetTest1")
    public Mono<String> getTest(){
        return Mono.fromCallable(()->{
            Thread.sleep(5000);
            return "success";
        });
    }
    @GetMapping("/GetTest2/{param}")
    public Mono<String> getTest2(@PathVariable("param")String param){
        return Mono.fromCallable(()->{
            Thread.sleep(500);
            return "success param = " + param;
        });
    }
    @PostMapping("/GetTest3")
    public Mono<String> getTest3(String param){
        return Mono.fromCallable(()->{
            Thread.sleep(500);
            return "success param = " + param;
        });
    }
    @PostMapping("/GetTest4")
    public Mono<String> getTest4(@RequestBody Map<String,Object> map){
        return Mono.fromCallable(()->{
            Thread.sleep(500);
            return "success param = " + map.toString();
        });
    }
//    @GetMapping(value = "/GetTest5",produces = "text/event-stream")
    @GetMapping(value = "/GetTest5",produces = MediaType.TEXT_EVENT_STREAM_VALUE)
    public Flux<String> getTest5(){
        return Flux.fromStream(IntStream.range(1,5).mapToObj(i->{
            try {
                TimeUnit.SECONDS.sleep(2);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            return "localhost - > "+i;
        }));
    }
}
  
 - 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
文章来源: blog.csdn.net,作者:小毕超,版权归原作者所有,如需转载,请联系作者。
原文链接:blog.csdn.net/qq_43692950/article/details/107449684
- 点赞
- 收藏
- 关注作者
 
             
           
评论(0)