Spring 5 的真实控制器示例:Web Reactive

A real-world controller example with Spring 5: Web Reactive

我想与 Spring 一起参与反应式编程世界。据我了解,it gives me a choice between two different paradigms: the annotation-based (with well-known to us @Controller, @RequestMapping) and the reactive one (which is intended to resolve an "Annotation Hell").

我的问题是不了解典型的反应式控制器的外观。我可以在我的控制器中使用三个概念接口 class:

HandlerFunction<T> (1) - 我为每个特定的 ServerRequest 定义一个方法 returns 一个具体的 HandlerFunction<T> 实例,然后向路由器注册这些方法。对吗?

RouterFunction (2) 和 FilterFunction (3) - 是否有一个特定的地方应该放置所有 RequestPredicates 和相应的 HandlerFunctions?或者我可以在每个控制器中单独进行(就像我以前使用注释方法所做的那样)吗?如果是这样,那么如何通知全局处理程序(路由器,如果有的话?)从这个控制器应用这个路由器部分?

这就是我现在对反应式控制器的看法 "template":

public class Controller {
    // handlers
    private HandlerFunction<ServerResponse> handleA() {
        return request -> ok().body(fromObject("a"));
    }

    // router
    public RouterFunction<?> getRouter() {
        return route(GET("/a"), handleA()).and(
               route(GET("/b"), handleB()));
    }

    // filter
    public RouterFunction<?> getFilter() {
        return route(GET("/c"), handleC()).filter((request, next) -> next.handle(request));
    }
}

最后,如何说它是一个控制器,而不用注解来标记它?

我已经阅读了 Spring 参考资料以及官方博客上与此问题相关的所有帖子。有很多样本,但所有样本都是断章取义的(恕我直言),我无法 assemble 将它们完整地呈现出来。

如果您能提供有关如何组织这些功能之间的交互的真实示例和良好实践,我将不胜感激。

就我而言:

RouterFunction 是最接近 @Controller 的类似物(@RequestMapping 恰好是新的 Spring approach:

Incoming requests are routed to handler functions with a RouterFunction (i.e. Function>). A router function evaluates to a handler function if it matches; otherwise it returns an empty result. The RouterFunction has a similar purpose as a @RequestMapping annotation. However, there is an important distinction: with the annotation your route is limited to what can be expressed through the annotation values, and the processing of those is not trivial to override; with router functions the processing code is right in front of you: you can override or replace it quite easily.

然后代替 Spring 在主方法中启动 SpringApplication.run 您的 运行 服务器手动通过 :

// route is your route function
HttpHandler httpHandler = RouterFunctions.toHttpHandler(route); 
HttpServlet servlet = new ServletHttpHandlerAdapter(httpHandler);
Tomcat server = new Tomcat();
Context rootContext = server.addContext("",
System.getProperty("java.io.tmpdir"));
Tomcat.addServlet(rootContext, "servlet", servlet);
rootContext.addServletMapping("/", "servlet");
tomcatServer.start();

有反应式和non-reactive两种方法。 Spring github

上有说明

这不是真实世界的例子,但到目前为止我是这样看待某种组织的:

https://github.com/LearningByExample/reactive-ms-example