2017-01-05 61 views
4

我希望通过Spring参与反应式编程世界。我意识到,it gives me a choice between two different paradigms:基于注释(与我们熟知的@Controller, @RequestMapping)和反应性的(which is intended to resolve an "Annotation Hell")。Spring 5的真实世界控制器示例:Web反应性

我的问题是缺乏一个典型的无功控制器将如何看起来像。有三种概念接口,我可以在控制器类使用:

HandlerFunction<T>(1) - I定义的方法为每个特定ServerRequest 它返回一个具体HandlerFunction<T>实例,则注册这些方法与路由器。对?

RouterFunction(2)和FilterFunction(3) - 有其中所有RequestPredicate s的对应HandlerFunction S的关系被放置在特定的位置?或者我可以在每个控制器中单独执行它(就像我以前用注释方法做的那样)?如果是这样,那么如何通知一个全局处理程序(路由器,如果有的话?)从这个控制器应用这个路由器部分?

这是我所看到的反应器“模板”现在:

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参考资料以及与此问题相关的所有帖子。有大量的样本,但所有这些样本都被撤消(恕我直言),我无法将它们组装成完整的图片。

如果你能提供一个真实的例子和如何组织这些功能之间的交互的良好实践,我将不胜感激。

+1

这可能是因为造成过于宽泛,特别是因为当API可能大部分是稳定的,Spring 5在技术上甚至还没有在RC中(而Spring Security Reactive仍然处于重大发展阶段)。 – chrylis

+3

_“带有Spring的反应式编程世界...给了我两种不同的范例之间的选择:基于注释的和反应式的_”应该是“基于注释和功能的注释”。两者都是被动的,只有基于注释的风格才有经典控制器。 – zeroflagL

+1

我认为这里提出的是“如何组织代码”,特别是在功能模型的情况下。我也为此付出了努力。示例代码会让我们在一个长的NLP样式链中声明所有请求映射(路由的)。这会在不需要在同一个类文件中提及的路由之间引入耦合,并且如果我尝试创建特定于处理程序的类,它们的路由将单独存储。 基于注解的方法看起来可能会解决这些问题,但我还没有得到该方法的工作。即使它工作,为什么有一个功能方法? – allenru

回答

2

就我而言:

RouterFunction是在新Spring approach方面最接近的模拟到@Controller@RequestMapping精确):

传入请求路由到处理函数与 RouterFunction(即功能>)。如果匹配,则路由器函数的处理函数计算结果为 ;否则返回空结果。 RouterFunction具有与@RequestMapping 注释类似的用途。但是,有一个重要的区别:通过 注释,您的路线仅限于可通过 注释值表达的内容,并且对这些注释值的处理并不重要;对于 重写而言,这些并不重要;通过路由器功能,处理代码正好在您的前面 :您可以很容易地覆盖或替换它。

然后,而不是春季启动SpringApplication.run在main方法手动将运行服务器由:

// 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(); 

有反应性和非反应性的方法。它是在春天所示github

+0

感谢您的回复,但我最感兴趣的是控制器的外观以及如何组织这些控制器之间的交互。你的代码片段明确地说明了当我们收集全局/共享事物时会发生的混乱情况(比如'RouterFunction'正在通过将所有东西一次放入一个地方而变得越来越复杂)。 – Andrew

+0

感谢github链接,但是我真的不想在'main'方法或者'configureGlobalRouting'这样的方法中写入所有路由逻辑。 – Andrew

+0

@AndrewTobilko我可以建议我将做类似于类似于以下新弹簧的ratpack框架:https://ratpack.io/manual/current/spring.html#the_spring_convenience_class –