【问题标题】:How is @RequestMapping implemented to support flexible signatures@RequestMapping 如何实现以支持灵活的签名
【发布时间】:2015-02-19 22:54:02
【问题描述】:

正如我们已经知道的那样,带有@RequestMapping 注释的处理程序方法可以具有非常灵活的签名,并且可以以任意顺序进行。所以我们可能在控制器中有如下方法

@RequestMapping(value = "/helloworld")
public String helloworld(){
    ...
}

或

@RequestMapping(value = "/helloworld")
public String helloworld(HttpServletResponse response, HttpServletRequest request){
    ...
}

或

@RequestMapping(value = "/helloworld")
public String helloworld(HttpServletRequest request, HttpServletResponse response){
    ...
}

Spring 总能找到正确的方法来调用和传递正确的参数。我想知道幕后的实现,有人可以向我解释吗?提前致谢。

【问题讨论】:

    标签: java spring-mvc annotations


    【解决方案1】:

    在启动时,Spring 使用反射来扫描您的 @Controller 方法,以查找带有 @RequestMapping 注释的方法。它注册相应的Method 实例。它创建了一个内部地图样式的数据结构,以便它可以将请求 URL 与处理程序方法匹配。

    并行地,它构造了一个List(各种)HandlerMethodArgumentResolver 实例。这些是策略对象。 Spring 对每个 supported parameter type 都有一个实现。

    一旦它有了处理方法,它就会得到它的所有参数类型。它遍历HandlerMethodArgumentResolvers 列表,检查当前HandlerMethodArgumentResolver 是否支持参数类型。如果是这样,它会使用它来解析要用作参数的值。如果没有,它会继续下一个。如果没有人能做到,Spring 会抛出异常。它收集所有这些值。 Spring 最终使用收集的参数值在 Method 对象上按顺序调用 invoke。

    【讨论】:

    • 所以spring总是要循环遍历list或者map来找到每个请求调用的方法?似乎有一些开销。
    • @DinoTw 这是唯一的方法(或多或少一些智能排序),这样您就可以根据您在@RequestMapping 中提供的所有属性(标题、路径、路径变量等)。
    【解决方案2】:

    这是相当简单的机制。首先使用反射列出所有方法。然后带有此注释的每个方法(spring 使用许多不同的注释)都由某种控制器处理器处理。并再次使用反射弹簧一一检查每个参数。如果参数具有在某个映射或集合中定义的类型,则从弹簧上下文中选择该类型的对象并将其放入有序的参数集合中。当 spring 扫描所有参数并找到所有要传递给该方法的对象时,它会使用准备好的参数执行该方法 - 再次通过反射。

    ps。如果您不知道它是如何工作的,请尝试自己编写类似的功能。真的很简单

    【讨论】:

    • 感谢您的解释,我会自己尝试一些反思。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-02-24
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多