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

Spring 当添加相同类型的自定义解析器时,默认参数解析器会发生什么情况?,spring,spring-mvc,Spring,Spring Mvc,所以我想将最大可分页大小值限制为10(示例值),我可以这样做: @Configuration public class MvcConfiguration extends WebMvcConfigurerAdapter { @Override public void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) { super.addArgumen

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

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

1。配置阶段

扩展
WebMvcConfigurerAdapter
并在
AddArgumentResolver
中添加自定义解析程序时(跳过大量配置代码),实际上是将它们添加到
RequestMappingHandlerAdapter
bean内部保存初始化期间提供的所有解析程序列表。(). 之后,它们将与默认解析程序组合。正如您可以从中看到的,
PageableHandlerMethodArgumentResolver
实际上不是默认解析器列表的一部分,而是来自某个配置类。在我的例子中(下面的屏幕截图),
spring-boot-starter-data-rest
配置类提供了不同版本的PageableHandler:
hateoaspageablehandler-methodargumentresolver

2。解析程序顺序

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

我突出显示了custom resolver
MyPageableHandlerMethodArgumentResolver
,注册方式与您在问题代码中的注册方式相同

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

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

正如您从源代码中看到的,结果被缓存,并且对于相同的参数类型不再进行迭代

supports(MethodParameter)
上返回
true
HandlerMethodArgumentResolver
用于解析方法参数。如果您添加的内容返回
true
,则即使另一个冲突解决程序支持它,也会使用它。这里肯定还有其他原因,用户添加的冲突解决程序可能会被优先排序,或者如果存在相同类型的冲突解决程序,Spring将不再添加其预设的冲突解决程序,但我不确定是否存在这种情况。每个方法参数上只有一个解析器工作。所以基本上说,现在它工作只是巧合,对吗由于不相关的
@Configuration
类的处理顺序不确定,所以恰好我的配置排在第一位。@Antoniossss我认为是的,默认情况下每个配置的优先级都是
最低的,但您可以使用
@order
来确保自定义配置的优先级。因此,当
List
自动连接进来时,它会根据bean的
顺序在内部进行排序。至于来自的解析器,我认为,它的配置方式是,如果您从这个类进行扩展,覆盖
addArgumentResolver
并且不要调用超级像
HateoAsawareStringDataWebConfiguration
你没有得到“默认”resolversAllright,所有正确的方法都是在那里使用和设置resolver。谢谢你discussion@Antoniossss是的,我想是的。实际上,您可以使用
PageableHandlerMethodArgumentResolverCustomizer
修改现有bean,就像这样
for (HandlerMethodArgumentResolver methodArgumentResolver : this.argumentResolvers)
    if (methodArgumentResolver.supportsParameter(parameter)) {
        result = methodArgumentResolver;
        this.argumentResolverCache.put(parameter, result);
        break;
    }