首先列上入门的参考资料:
(1)什么是响应式编程——响应式Spring的道法术器
(2)响应式流——响应式Spring的道法术器
(3)lambda与函数式——响应式Spring的道法术器
(4)Reactor 3快速上手——响应式Spring的道法术器
(5)Spring WebFlux快速上手——响应式Spring的道法术器
(总纲目)响应式Spring的道法术器(Spring WebFlux 教程)
按照这些资料挨个看过来,基本就入门了,这里我不扯那么多理论,直接以Demo入门:
(一)Demo目的
下面我们用函数式的方式开发两个Endpoint:
/time
返回当前的时间;
/date
返回当前的日期。
(二)WebFlux的函数式开发基本流程
1.创建统一存放处理时间的Handler类
这里的Handler类相当于SpringMVC中Controller层中的方法体
/**
* 引入静态方法ok()
*/
import static org.springframework.web.reactive.function.server.ServerResponse.ok;
/**
* @author 咸鱼
* @date 2018/6/28 16:38
*/
@Component
public class TimeHandler {
/**
* 在响应式编程中,请求和响应不再是HttpServletRequest和HttpServletResponse,而是变成了ServerRequest和ServerResponse
* @param request 请求
* @param response 响应
* @return Mono和Flux主要用于响应式编程的“异步”数据流处理,不像我们以前直接返回String/List<T>....,而是直接包装成
* Mono和Flux对象。见文知意,Mono主要用于返回单个数据,Flux用于返回多个数据。比如我们要根据id查询某个User,
* 那返回的肯定就是一个User,那么需要包装成Mono<User>;若我们需要获取所有User,这是一个集合,我们需要包装成
* Flux<User>。这里的单个数据并不是指一个数据,而是指封装好的一个对象;多个数据就是多个对象
* ServerRequest request, ServerResponse response
*/
public Mono<ServerResponse> getTime(ServerRequest request){
//固定格式就是这样
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 request){
return ok().contentType(MediaType.TEXT_PLAIN).body(
Mono.just("Now is " + new SimpleDateFormat("yyyy-MM-dd").format(new Date())), String.class);
}
2.在Spring容器配置RouterFunction
这里的Handler类相当于SpringMVC中Controller层中的映射路径(@RequestMapping)
/**
* 引入静态路由“router”
*/
import static org.springframework.web.reactive.function.server.RequestPredicates.GET;
import static org.springframework.web.reactive.function.server.RouterFunctions.route;
/**
* @author 咸鱼
* @date 2018/6/28 16:55
*/
@Configuration
public class RouterConfig {
private TimeHandler timeHandler;
@Autowired
public RouterConfig(TimeHandler timeHandler) {
this.timeHandler = timeHandler;
}
/**
* 注意方法名不能和类名重复
*/
@Bean
public RouterFunction<ServerResponse> timeRouter(){
/**
* 路由的写法也是固定的,第一个参数:路径,第二个参数:方法
* 这里的转换成lambda表达式是:request -> timeHandler.getTime(request),隐藏了一个ServerRequest参数,所以
* TimeHandler类中的方法都必须有一个参数“ServerRequest”
*/
return route(GET("/time"), timeHandler::getTime)
.andRoute(GET("/date"), timeHandler::getDate);
}
}