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

2023-12-15

所以我想将最大可分页大小值限制为 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) {

事实上,这会起作用,我无法将页面大小设置为> 10,但我很好奇为什么? Spring 创建的情况发生了什么PageableHandlerMethodArgumentResolver?为什么要考虑此实例而不是默认实例?毕竟,我不会在这里更换解析器,只是添加一个新的解析器。


1. 配置阶段

当你延长WebMvcConfigurerAdapter并添加自定义解析器addArgumentResolvers,(跳过大量配置代码)您实际上是将它们添加到请求映射处理适配器 RequestMappingHandlerAdapterbean 在内部保存初始化期间提供的所有解析器的列表。 (WebMvc配置支持)。之后它们与默认解析器组合。正如你可以看到的源代码, 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;
    }

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

添加相同类型的自定义解析器时,默认参数解析器会发生什么情况? 的相关文章

随机推荐