添加相同类型的自定义解析程序时,默认参数解析程序会发生什么?

时间:2017-10-18 23:53:55

标签: spring spring-mvc

所以我想将最大可分页大小值限制为10(示例值),我可以这样做:

@Configuration
public class MvcConfiguration extends WebMvcConfigurerAdapter {

    @Override
    public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
        super.addArgumentResolvers(argumentResolvers);
        PageableHandlerMethodArgumentResolver resolver = new PageableHandlerMethodArgumentResolver();
        resolver.setMaxPageSize(10);
        argumentResolvers.add(resolver);
    }
}
像这样的

和delcare控制器方法

   @RequestMapping(name = "list")
    public String listUsers(@PageableDefault(size = 5, page = 0) Pageable pageable) {

确实,这样可行,我无法将页面大小设置为&gt;但我很好奇为什么? Spring创建的PageableHandlerMethodArgumentResolver发生了什么?为什么要考虑这个实例而不是默认实例?毕竟,我不是在这里替换解析器,只是添加一个新的解析器。

1 个答案:

答案 0 :(得分:3)

<强> 1。配置阶段

扩展WebMvcConfigurerAdapter并在addArgumentResolvers中添加自定义解析器(跳过大量配置代码)时,实际上是将它们添加到RequestMappingHandlerAdapter RequestMappingHandlerAdapter bean内部列表中在初始化期间提供的所有解析器。 (WebMvcConfigurationSupport)。之后,它们与默认解析器结合使用。正如您在source code中看到的那样,PageableHandlerMethodArgumentResolver实际上并不是默认解析器列表的一部分,而是来自某些配置类。在我的情况下(下面的屏幕截图),spring-boot-starter-data-rest配置类提供了不同版本的PageableHandler:HateoasPageableHandlerMethodArgumentResolver

<强> 2。解析器订单

自定义解析程序是在内置解析程序(source)之后订购的。所以让我们检查一下并调用一些控制器,但先将断点放在RequestMappingHandlerAdapter.invokeHandlerMethod()中。从这里我们可以看到RequestMappingHandlerAdapter

的内部状态

enter image description here

我突出显示了自定义解析程序MyPageableHandlerMethodArgumentResolver,其注册方式与您在问题代码中的注册方式相同。

实际解析参数的代码在HandlerMethodArgumentResolverComposite中。它是简单的循环,这意味着将使用第一个注册的HandlerMethodArgumentResolver

for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers)
    if (methodArgumentResolver.supportsParameter(parameter)) {
        result = methodArgumentResolver;
        this.argumentResolverCache.put(parameter, result);
        break;
    }

从源代码中可以看出,结果是缓存的,并且永远不会再次针对相同的参数类型进行迭代。