========================1五、高级篇幅之SpringBoot2.0响应式编程 ================================html
一、SprinBoot2.x响应式编程简介
简介:讲解什么是reactive响应式编程和使用的好处java
一、基础理解:
依赖于事件,事件驱动(Event-driven)
一系列事件称为“流”
异步
非阻塞react
观察者模式web
网上的一个例子:
int b= 2;
int c=3
int a = b+c //命令式编程后续b和c变化,都不影响a
b=5;redis
int b= 2;
int c= 3
int a = b+c //响应式编程中,a的变化,会和b、c的变化而变化(事件驱动)
b=5;spring
二、官网:https://docs.spring.io/spring-boot/docs/2.1.0.BUILD-SNAPSHOT/reference/htmlsingle/#boot-features-webflux
SpingBoot2底层是用spring5,开始支持响应式编程,Spring又是基于Reactor试下响应式。编程
学习资料
一、reactive-streams学习资料:http://www.reactive-streams.org/
二、web-flux相关资料:https://docs.spring.io/spring/docs/current/spring-framework-reference/web-reactive.html#spring-webfluxapi
二、SpringBoot2.x响应式编程webflux介绍
简介:讲解SpringBoot2.x响应式编程介绍 Mono、Flux对象和优缺点
一、Spring WebFlux是Spring Framework 5.0中引入的新的反应式Web框架
与Spring MVC不一样,它不须要Servlet API,彻底异步和非阻塞,并 经过Reactor项目实现Reactive Streams规范。
RxJava数组
二、Flux和Mono User List<User>
1)简单业务而言:和其余普通对象差异不大,复杂请求业务,就能够提高性能
2)通俗理解:
Mono 表示的是包含 0 或者 1 个元素的异步序列
mono->单一对象 User redis->用户ID-》惟一的用户Mono<User>
Flux 表示的是包含 0 到 N 个元素的异步序列
flux->数组列表对象 List<User> redis->男性用户->Flux<User>
Flux 和 Mono 之间能够进行转换app
三、Spring WebFlux有两种风格:基于功能和基于注解的。基于注解很是接近Spring MVC模型,如如下示例所示:
第一种:
@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){
// ...
}
}
第二种: 路由配置与请求的实际处理分开
@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);
}
}
@Component
public class UserHandler {
公共 Mono <ServerResponse> getUser(ServerRequest请求){
// ...
}
public Mono <ServerResponse> getUserCustomers(ServerRequest request){
// ...
}
公共 Mono <ServerResponse> deleteUser(ServerRequest请求){
// ...
}
}
四、Spring WebFlux应用程序不严格依赖于Servlet API,所以它们不能做为war文件部署,也不能使用src/main/webapp目录
五、能够整合多个模板引擎
除了REST Web服务外,您还可使用Spring WebFlux提供动态HTML内容。Spring WebFlux支持各类模板技术,包括Thymeleaf,FreeMarker
三、SpringBoot2.x webflux实战
简介:webflux响应式编程实战
一、WebFlux中,请求和响应再也不是WebMVC中的(Http)ServletRequest和(Http)ServletResponse,而是ServerRequest和ServerResponse
二、加入依赖,若是同时存在spring-boot-starter-web,则会优先用spring-boot-starter-web
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
测试
localhost:8080/api/v1/user/test
三、启动方式默认是Netty,8080端口
package com.example.demo.controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import reactor.core.publisher.Mono; @RestController @RequestMapping("/api/v1/user") public class UserController { @GetMapping("/test") public Mono<String> test(){ return Mono.just("hello xiaod"); } }
四、参考:https://spring.io/blog/2016/04/19/understanding-reactive-types
package com.example.demo.service; import java.util.Collection; import java.util.HashMap; import java.util.Map; import org.springframework.stereotype.Service; import com.example.demo.domain.User; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @Service public class UserService { private static final Map<String, User> dataMap = new HashMap<>(); static{ dataMap.put("1", new User("1", "小X老师")); dataMap.put("2", new User("2", "小D老师")); dataMap.put("3", new User("3", "小C老师")); dataMap.put("4", new User("4", "小L老师")); dataMap.put("5", new User("5", "小A老师")); dataMap.put("6", new User("6", "小S老师")); dataMap.put("7", new User("7", "小S老师")); } public Flux<User> list(){ Collection<User> list=UserService.dataMap.values(); return Flux.fromIterable(list); } public Mono<User> getById(final String id){ return Mono.justOrEmpty(UserService.dataMap.get(id)); } public Mono<User> del(final String id){ return Mono.justOrEmpty(UserService.dataMap.remove(id)); } }
package com.example.demo.controller; import java.time.Duration; import org.springframework.http.MediaType; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import com.example.demo.domain.User; import com.example.demo.service.UserService; import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; @RestController @RequestMapping("/api/v1/user") public class UserController { private UserService userService; public UserController(final UserService userService) { this.userService = userService; } @GetMapping("/test") public Mono<String> test(){ return Mono.just("hello xiaod"); } @GetMapping("find") public Mono<User> findByid(final String id){ return userService.getById(id); } /** * 功能描述:删除用户 * @param id * @return */ @GetMapping("del") public Mono<User> del(final String id){ return userService.del(id); } @GetMapping(value="list",produces=MediaType.APPLICATION_STREAM_JSON_VALUE) public Flux<User> list(){ return userService.list().delayElements(Duration.ofSeconds(2)); } }
能够用于服务推送
四、WebFlux客户端WebClient讲解
简介:讲解SpringBoot2.x WebFlux客户端WebClient的介绍和使用
一、反应式客户端
官网地址:https://docs.spring.io/spring-boot/docs/2.1.0.BUILD-SNAPSHOT/reference/htmlsingle/#boot-features-webclient