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

标签 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 Controller 方法

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

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

最佳答案

<强>1。配置阶段

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

<强>2。解析器顺序

自定义解析器在内置解析器之后排序 ( source )。所以让我们检查一下并调用一些 Controller ,但在 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;
    }

而且正如您从源代码中看到的那样,结果被缓存并且不会针对相同的参数类型再次迭代。

关于spring - 添加相同类型的自定义解析器时,默认参数解析器会发生什么情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46820935/

相关文章:

java - spring boot 集成测试中获取 org.hibernate.LazyInitializationException

java - HTTP 请求不会经过 Controller

java - Spring Boot 自动 JSON 到 Controller 中的对象

javascript - 通过javascript创建一个spring表单并附加到div中

java - SAML 2.0 支持 Java Jersey Web/REST 应用程序

java - 如何在 Spring MVC 中处理 RESTful 删除

java - EL表达式可以访问作用域中的子对象的子对象吗?

java - Spring MVC 404错误http请求

java - 告诉 Hibernate 仅让数据库在值为 null 时生成值

java - Spring Batch - 如何使用从 REST API 请求收到的文件名启 Action 业