복붙노트

[SPRING] 동일한 유형의 사용자 정의 리졸버가 추가 될 때 기본 인수 분석기에서 어떤 일이 발생합니까?

SPRING

동일한 유형의 사용자 정의 리졸버가 추가 될 때 기본 인수 분석기에서 어떤 일이 발생합니까?

그래서 최대 페이지 크기 값을 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);
    }
}

이렇게 컨트롤러 메소드를 선언하십시오.

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

실제로 이것은 작동 할 것이지만 페이지 크기를 10보다 크게 설정할 수는 없지만 왜 궁금합니까? PageableHandlerMethodArgumentResolver가 Spring에 어떤 일이 일어나고 있습니까? 이 인스턴스가 기본 인스턴스가 아니라 왜 고려됩니까? 결국, 나는 여기서 새로운 결정자를 추가하는 대신 여기의 결정자를 대체 할 수 없다.

해결법

  1. ==============================

    1.1. 구성 단계

    1. 구성 단계

    WebMvcConfigurerAdapter를 확장하고 addArgumentResolvers에 사용자 정의 해결자를 추가하면 (실제로 많은 구성 코드를 건너 뛰고) RequestMappingHandlerAdapter에 실제로 추가합니다. RequestMappingHandlerAdapter bean은 초기화 중에 제공된 모든 해결 자 목록을 내부적으로 저장합니다. (WebMvcConfigurationSupport). 그런 다음 기본 확인자와 결합됩니다. 그리고 소스 코드에서 볼 수 있듯이, PageableHandlerMethodArgumentResolver는 실제로 기본 해결 자 목록의 일부가 아니지만 일부 구성 클래스에서 제공됩니다. 제 경우 (아래 스크린 샷)에서는 spring-boot-startter-data-rest 구성 클래스가 다른 버전의 PageableHandler를 제공합니다. HateoasPageableHandlerMethodArgumentResolver

    2. 주문 해결

    사용자 정의 리졸버는 기본 제공 리 소스 (소스) 다음에 정렬됩니다. 그래서 이것을 확인하고 컨트롤러를 호출 할 수 있지만 먼저 RequestMappingHandlerAdapter.invokeHandlerMethod ()에 중단 점을 넣으십시오. 여기에서 RequestMappingHandlerAdapter의 내부 상태를 볼 수 있습니다.

    나는 당신이 질문 코드에서했던 것과 같은 방식으로 등록 된 사용자 정의 해석기 PageableHandlerMethodArgumentResolver를 강조했다.

    그리고 실제로 인수를 해결하는 코드는 HandlerMethodArgumentResolverComposite에 있습니다. 이것은 단순한 루프이며 처음 등록 된 HandlerMethodArgumentResolver가 사용될 것임을 의미합니다.

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

    그리고 소스 코드에서 볼 수 있듯이 결과는 캐시되고 동일한 매개 변수 유형에 대해 다시 반복되지 않습니다.

  2. from https://stackoverflow.com/questions/46820935/what-is-happening-with-default-argument-resolver-when-custom-resolver-for-same-t by cc-by-sa and MIT license