2017-10-18 2 views
1

Deshalb möchte ich maximal seitenwechselbar Größe Wert auf 10 (Beispielwert) begrenzen, und ich kann dies tun, wie folgt aus:Was passiert mit dem Standard-Argument-Resolver, wenn ein benutzerdefinierter Resolver für denselben Typ hinzugefügt wird?

@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); 
    } 
} 

und delcare Controller-Methode wie diese

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

der Tat wird diese Arbeit Ich kann die Seitengröße nicht auf> 10 einstellen, aber ich bin neugierig warum? Was passiert mit Spring erstellt PageableHandlerMethodArgumentResolver? Warum wird diese Instanz berücksichtigt und nicht die Standardinstanz? Schließlich kann ich Resolver hier nicht ersetzen, sondern nur einen neuen hinzufügen.

+0

Der 'HandlerMethodArgumentResolver', der '' true' auf 'supports (MethodParameter)' zurückgibt, wird verwendet, um den Methodenparameter aufzulösen. Wenn das, was Sie hinzugefügt haben, "true" zurückgibt, wird das verwendet, auch wenn der andere Resolver es unterstützt. Hier muss noch etwas anderes ablaufen, vom Benutzer hinzugefügte Resolver könnten priorisiert sein oder Spring fügt seine voreingestellten Resolver nicht mehr hinzu, wenn ein Resolver des gleichen Typs existiert, aber ich bin mir da nicht sicher. Nur ein Resolver funktioniert für jeden Methodenparameter. –

Antwort

1

1. Projektierungsphase

Wenn Sie WebMvcConfigurerAdapter erweitern und benutzerdefinierte Resolver in addArgumentResolvers, (Überspringen viele Konfigurationscode) fügen Sie sie tatsächlich aller Resolvern speichert intern die Liste RequestMappingHandlerAdapterRequestMappingHandlerAdapter Bean hinzufügen, zur Verfügung gestellt während der Initialisierung. (WebMvcConfigurationSupport). Danach werden sie mit Standard-Resolvern kombiniert. Und wie Sie aus der source code sehen können, ist PageableHandlerMethodArgumentResolver nicht Teil der Standard-Resolver-Liste, sondern kommt aus einer Konfigurationsklasse. Und in meinem Fall (Abbildung unten) die spring-boot-starter-data-rest Konfigurationsklassen bieten andere Version von PageableHandler: HateoasPageableHandlerMethodArgumentResolver

2. Auflöser Bestellen

Individuelle Resolver werden bestellt nach Einbau-one (source). Also lasst uns das überprüfen und einen Controller aufrufen, aber setzt zuerst den Breakpoint in RequestMappingHandlerAdapter.invokeHandlerMethod(). Von hier aus können wir den inneren Zustand von RequestMappingHandlerAdapter

enter image description here

ich hervorgehoben benutzerdefinierte Resolver MyPageableHandlerMethodArgumentResolver, registriert die gleiche Art und Weise Sie haben in Ihrer Frage Code.

Und der Code, der Argumente tatsächlich löst, ist in HandlerMethodArgumentResolverComposite. Es ist einfach Schleife und es bedeutet, dass die erste registrierte HandlerMethodArgumentResolver wird

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

verwendet werden und wie Sie aus dem Quellcode sehen, wird das Ergebnis im Cache gespeichert und nie wiederholt wieder für den gleichen Parameter Typen.

+0

Also im Grunde funktioniert es gerade jetzt durch einen Zufall, habe ich recht? - Da die '@ Configuration' -Klassen nicht mit der Verarbeitungsreihenfolge übereinstimmen, ist es einfach so, dass meine Konfiguration zuerst kommt. – Antoniossss

+0

@Antoniossss Ich denke ja, jede Konfiguration hat standardmäßig 'LOWEST_PRECEDENCE', aber Sie können' @ Order' verwenden, um die Priorität für Ihre benutzerdefinierten Konfigurationen zu gewährleisten. Also, wenn 'List in [DelegatingWebMvcConfiguration]' autowired (https://github.com/spring-projects/spring-framework/blob/master/spring-webmvc/src/main/java/org/springframework/web/ servlet/config/annotation/DelegatingWebMvcConfiguration.Java # L48-L53), wird intern nach der 'Reihenfolge' der Beans sortiert. – varren

+0

Für Resolver, die aus der [SpringDataWebConfiguration] stammen (https://github.com/spring-projects/spring-data-commons/blob/master/src/main/java/org/springframework/data/web/config/ SpringDataWebConfiguration.java # L138-L149), ich denke, es ist so konfiguriert, dass, wenn Sie von dieser Klasse erweitern, überschreiben 'addArgumentResolvers' und nicht super wie' HateoasAwareSpringDataWebConfiguration' aufrufen Sie nicht die "Standard" Resolver – varren

Verwandte Themen