这是我参与11月更文挑战的第1天,活动详情查看:2021最后一次更文挑战。
最近工作中需要用到响应式编程。之前一直是spring web开发,对响应式编程知之甚少。webFlux相对于spring mvc而言,又是一种web开发框架,熟悉的spring mvc开发通过@RestController注解以及@RequestMapping等注解的配合使用 比如: @RestController @RequestMapping("flux") public class MonoFluxController {
@GetMapping("/index")
public String index() {
return "index";
}
}
而spring5.0版本新引入的基于Reactive Streams的Spring WebFlux框架,主要基于Router Functions、WebFlux、Reactive Streams三个新组件;
- Router Functions: 对标@Controller,@RequestMapping等标准的Spring MVC注解,提供一套函数式风格的API,用于创建Router,Handler和Filter。
- WebFlux: 核心组件,协调上下游各个组件提供响应式编程支持。
- Reactive Streams: 一种支持背压(Backpressure)的异步数据流处理标准,主流实现有RxJava和Reactor,Spring WebFlux默认集成的是Reactor。 Spring WebFlux都会将其输入输出流适配成Flux格式,以便进行统一处理。 值得一提的是,除了新的Router Functions接口,Spring WebFlux同时支持使用老的Spring MVC注解声明Reactive Controller。和传统的MVC Controller不同,Reactive Controller操作的是非阻塞的ServerHttpRequest和ServerHttpResponse,而不再是Spring MVC里的HttpServletRequest和HttpServletResponse。
// WebFlux(返回的是Mono) vWebFlux的好处:能够以固定的线程来处理高并发
@GetMapping("/2")
private Mono<String> get2() {
log.info("get2 start");
Mono<String> result = Mono.fromSupplier(() -> createStr());
log.info("get2 end.");
return result;
}
Flux和Mono是Reactor的数据流类型,Flux支持发送0次和N次,Mono支持发送0次和1次,如果返回的数据集,需要用Flux。响应式编程的开发需对的JDK8的Lamda表达式有一定的学习和使用。 实现spring boot的webFlux方式有两种,一种基于spring webmvc的注解方式,一种基于函数式编程的Hander和Router,这里主要实现第二种。 创建一个spring boot工程,添加POM依赖包 org.springframework.boot spring-boot-starter-webflux
编写一个处理时间的handler
@Component
public class TimeHandler {
public Mono<ServerResponse> getTime(ServerRequest serverRequest) {
return ok().contentType(MediaType.TEXT_PLAIN).body(Mono.just("Now is " + new SimpleDateFormat("HH:mm:ss").format(new Date())), String.class);
}
public Mono<ServerResponse> getDate(ServerRequest serverRequest) {
return ok().contentType(MediaType.TEXT_PLAIN).body(Mono.just("Today is " + new SimpleDateFormat("yyyy-MM-dd").format(new Date())), String.class);
}
}
注意TimeHandler是要加@Component注解或者@Cofiguration注解,注入spring容器。
再编写一个router
@Configuration
public class TimeRouter {
@Autowired
private TimeHandler timeHandler;
@Bean
public RouterFunction<ServerResponse> timerRouter() {
return route(GET("/time"), req -> timeHandler.getTime(req))
.andRoute(GET("/date"), timeHandler::getDate); // 这种方式相对于上一行更加简洁
}
}
TimeRouter同样注入。
这时,我们启动spring boot工程,谷歌浏览器输入:http://localhost:8080/time 输出:``` Now is 18:32:02
这样第一个简单的webFlux工程已经跑通了,下次会继续学习。