Skip to content

Commit ab0b0b3

Browse files
committed
Polish: simplify ControllerMethodResolver initialization
1 parent d24546a commit ab0b0b3

File tree

4 files changed

+87
-139
lines changed

4 files changed

+87
-139
lines changed

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/ControllerMethodResolver.java

Lines changed: 84 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2002-2017 the original author or authors.
2+
* Copyright 2002-2018 the original author or authors.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -24,8 +24,6 @@
2424
import java.util.Map;
2525
import java.util.Set;
2626
import java.util.concurrent.ConcurrentHashMap;
27-
import java.util.function.Function;
28-
import java.util.function.Supplier;
2927
import java.util.stream.Collectors;
3028

3129
import org.apache.commons.logging.Log;
@@ -40,7 +38,6 @@
4038
import org.springframework.http.codec.HttpMessageReader;
4139
import org.springframework.lang.Nullable;
4240
import org.springframework.util.Assert;
43-
import org.springframework.util.CollectionUtils;
4441
import org.springframework.util.ReflectionUtils;
4542
import org.springframework.web.bind.annotation.InitBinder;
4643
import org.springframework.web.bind.annotation.ModelAttribute;
@@ -53,7 +50,7 @@
5350
import org.springframework.web.reactive.result.method.SyncHandlerMethodArgumentResolver;
5451
import org.springframework.web.reactive.result.method.SyncInvocableHandlerMethod;
5552

56-
import static org.springframework.core.MethodIntrospector.selectMethods;
53+
import static org.springframework.core.MethodIntrospector.*;
5754

5855
/**
5956
* Package-private class to assist {@link RequestMappingHandlerAdapter} with
@@ -102,81 +99,112 @@ class ControllerMethodResolver {
10299
private final Map<Class<?>, SessionAttributesHandler> sessionAttributesHandlerCache = new ConcurrentHashMap<>(64);
103100

104101

105-
ControllerMethodResolver(ArgumentResolverConfigurer argumentResolvers,
106-
List<HttpMessageReader<?>> messageReaders, ReactiveAdapterRegistry reactiveRegistry,
107-
ConfigurableApplicationContext context) {
102+
ControllerMethodResolver(ArgumentResolverConfigurer customResolvers, ReactiveAdapterRegistry reactiveRegistry,
103+
ConfigurableApplicationContext context, List<HttpMessageReader<?>> readers) {
108104

109-
Assert.notNull(argumentResolvers, "ArgumentResolverConfigurer is required");
110-
Assert.notNull(messageReaders, "'messageReaders' is required");
105+
Assert.notNull(customResolvers, "ArgumentResolverConfigurer is required");
106+
Assert.notNull(readers, "'messageReaders' is required");
111107
Assert.notNull(reactiveRegistry, "ReactiveAdapterRegistry is required");
112108
Assert.notNull(context, "ApplicationContext is required");
113109

114-
ArgumentResolverRegistrar registrar;
110+
this.initBinderResolvers = initBinderResolvers(customResolvers, reactiveRegistry, context);
111+
this.modelAttributeResolvers = modelMethodResolvers(customResolvers, reactiveRegistry, context);
112+
this.requestMappingResolvers = requestMappingResolvers(customResolvers, reactiveRegistry, context, readers);
113+
this.exceptionHandlerResolvers = exceptionHandlerResolvers(customResolvers, reactiveRegistry, context);
114+
this.reactiveAdapterRegistry = reactiveRegistry;
115115

116-
registrar = ArgumentResolverRegistrar.configurer(argumentResolvers).basic();
117-
addResolversTo(registrar, reactiveRegistry, context);
118-
this.initBinderResolvers = registrar.getSyncResolvers();
116+
initControllerAdviceCaches(context);
117+
}
119118

120-
registrar = ArgumentResolverRegistrar.configurer(argumentResolvers).modelAttributeSupport();
121-
addResolversTo(registrar, reactiveRegistry, context);
122-
this.modelAttributeResolvers = registrar.getResolvers();
119+
private List<SyncHandlerMethodArgumentResolver> initBinderResolvers(
120+
ArgumentResolverConfigurer customResolvers, ReactiveAdapterRegistry reactiveRegistry,
121+
ConfigurableApplicationContext context) {
123122

124-
registrar = ArgumentResolverRegistrar.configurer(argumentResolvers).fullSupport(messageReaders);
125-
addResolversTo(registrar, reactiveRegistry, context);
126-
this.requestMappingResolvers = registrar.getResolvers();
123+
return initResolvers(customResolvers, reactiveRegistry, context, false, Collections.emptyList()).stream()
124+
.filter(resolver -> resolver instanceof SyncHandlerMethodArgumentResolver)
125+
.map(resolver -> (SyncHandlerMethodArgumentResolver) resolver)
126+
.collect(Collectors.toList());
127+
}
127128

128-
registrar = ArgumentResolverRegistrar.configurer(argumentResolvers).basic();
129-
addResolversTo(registrar, reactiveRegistry, context);
130-
this.exceptionHandlerResolvers = registrar.getResolvers();
129+
private static List<HandlerMethodArgumentResolver> modelMethodResolvers(
130+
ArgumentResolverConfigurer customResolvers, ReactiveAdapterRegistry reactiveRegistry,
131+
ConfigurableApplicationContext context) {
131132

132-
this.reactiveAdapterRegistry = reactiveRegistry;
133+
return initResolvers(customResolvers, reactiveRegistry, context, true, Collections.emptyList());
134+
}
133135

134-
initControllerAdviceCaches(context);
136+
private static List<HandlerMethodArgumentResolver> requestMappingResolvers(
137+
ArgumentResolverConfigurer customResolvers, ReactiveAdapterRegistry reactiveRegistry,
138+
ConfigurableApplicationContext context, List<HttpMessageReader<?>> readers) {
139+
140+
return initResolvers(customResolvers, reactiveRegistry, context, true, readers);
141+
}
142+
143+
private static List<HandlerMethodArgumentResolver> exceptionHandlerResolvers(
144+
ArgumentResolverConfigurer customResolvers, ReactiveAdapterRegistry reactiveRegistry,
145+
ConfigurableApplicationContext context) {
146+
147+
return initResolvers(customResolvers, reactiveRegistry, context, false, Collections.emptyList());
135148
}
136149

137-
private void addResolversTo(ArgumentResolverRegistrar registrar,
138-
ReactiveAdapterRegistry reactiveRegistry, ConfigurableApplicationContext context) {
150+
private static List<HandlerMethodArgumentResolver> initResolvers(ArgumentResolverConfigurer customResolvers,
151+
ReactiveAdapterRegistry reactiveRegistry, ConfigurableApplicationContext context,
152+
boolean supportDataBinding, List<HttpMessageReader<?>> readers) {
139153

140154
ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
155+
boolean requestMappingMethod = !readers.isEmpty() && supportDataBinding;
141156

142157
// Annotation-based...
143-
registrar.add(new RequestParamMethodArgumentResolver(beanFactory, reactiveRegistry, false));
144-
registrar.add(new RequestParamMapMethodArgumentResolver(reactiveRegistry));
145-
registrar.add(new PathVariableMethodArgumentResolver(beanFactory, reactiveRegistry));
146-
registrar.add(new PathVariableMapMethodArgumentResolver(reactiveRegistry));
147-
registrar.add(new MatrixVariableMethodArgumentResolver(beanFactory, reactiveRegistry));
148-
registrar.add(new MatrixVariableMapMethodArgumentResolver(reactiveRegistry));
149-
registrar.addIfRequestBody(readers -> new RequestBodyArgumentResolver(readers, reactiveRegistry));
150-
registrar.addIfRequestBody(readers -> new RequestPartMethodArgumentResolver(readers, reactiveRegistry));
151-
registrar.addIfModelAttribute(() -> new ModelAttributeMethodArgumentResolver(reactiveRegistry, false));
152-
registrar.add(new RequestHeaderMethodArgumentResolver(beanFactory, reactiveRegistry));
153-
registrar.add(new RequestHeaderMapMethodArgumentResolver(reactiveRegistry));
154-
registrar.add(new CookieValueMethodArgumentResolver(beanFactory, reactiveRegistry));
155-
registrar.add(new ExpressionValueMethodArgumentResolver(beanFactory, reactiveRegistry));
156-
registrar.add(new SessionAttributeMethodArgumentResolver(beanFactory, reactiveRegistry));
157-
registrar.add(new RequestAttributeMethodArgumentResolver(beanFactory, reactiveRegistry));
158+
List<HandlerMethodArgumentResolver> result = new ArrayList<>();
159+
result.add(new RequestParamMethodArgumentResolver(beanFactory, reactiveRegistry, false));
160+
result.add(new RequestParamMapMethodArgumentResolver(reactiveRegistry));
161+
result.add(new PathVariableMethodArgumentResolver(beanFactory, reactiveRegistry));
162+
result.add(new PathVariableMapMethodArgumentResolver(reactiveRegistry));
163+
result.add(new MatrixVariableMethodArgumentResolver(beanFactory, reactiveRegistry));
164+
result.add(new MatrixVariableMapMethodArgumentResolver(reactiveRegistry));
165+
if (!readers.isEmpty()) {
166+
result.add(new RequestBodyArgumentResolver(readers, reactiveRegistry));
167+
result.add(new RequestPartMethodArgumentResolver(readers, reactiveRegistry));
168+
}
169+
if (supportDataBinding) {
170+
result.add(new ModelAttributeMethodArgumentResolver(reactiveRegistry, false));
171+
}
172+
result.add(new RequestHeaderMethodArgumentResolver(beanFactory, reactiveRegistry));
173+
result.add(new RequestHeaderMapMethodArgumentResolver(reactiveRegistry));
174+
result.add(new CookieValueMethodArgumentResolver(beanFactory, reactiveRegistry));
175+
result.add(new ExpressionValueMethodArgumentResolver(beanFactory, reactiveRegistry));
176+
result.add(new SessionAttributeMethodArgumentResolver(beanFactory, reactiveRegistry));
177+
result.add(new RequestAttributeMethodArgumentResolver(beanFactory, reactiveRegistry));
158178

159179
// Type-based...
160-
registrar.addIfRequestBody(readers -> new HttpEntityArgumentResolver(readers, reactiveRegistry));
161-
registrar.add(new ModelArgumentResolver(reactiveRegistry));
162-
registrar.addIfModelAttribute(() -> new ErrorsMethodArgumentResolver(reactiveRegistry));
163-
registrar.add(new ServerWebExchangeArgumentResolver(reactiveRegistry));
164-
registrar.add(new PrincipalArgumentResolver(reactiveRegistry));
165-
registrar.addIfRequestBody(readers -> new SessionStatusMethodArgumentResolver());
166-
registrar.add(new WebSessionArgumentResolver(reactiveRegistry));
180+
if (!readers.isEmpty()) {
181+
result.add(new HttpEntityArgumentResolver(readers, reactiveRegistry));
182+
}
183+
result.add(new ModelArgumentResolver(reactiveRegistry));
184+
if (supportDataBinding) {
185+
result.add(new ErrorsMethodArgumentResolver(reactiveRegistry));
186+
}
187+
result.add(new ServerWebExchangeArgumentResolver(reactiveRegistry));
188+
result.add(new PrincipalArgumentResolver(reactiveRegistry));
189+
if (requestMappingMethod) {
190+
result.add(new SessionStatusMethodArgumentResolver());
191+
}
192+
result.add(new WebSessionArgumentResolver(reactiveRegistry));
167193

168194
// Custom...
169-
registrar.addCustomResolvers();
195+
result.addAll(customResolvers.getCustomResolvers());
170196

171197
// Catch-all...
172-
registrar.add(new RequestParamMethodArgumentResolver(beanFactory, reactiveRegistry, true));
173-
registrar.addIfModelAttribute(() -> new ModelAttributeMethodArgumentResolver(reactiveRegistry, true));
198+
result.add(new RequestParamMethodArgumentResolver(beanFactory, reactiveRegistry, true));
199+
if (supportDataBinding) {
200+
result.add(new ModelAttributeMethodArgumentResolver(reactiveRegistry, true));
201+
}
202+
203+
return result;
174204
}
175205

176-
private void initControllerAdviceCaches(@Nullable ApplicationContext applicationContext) {
177-
if (applicationContext == null) {
178-
return;
179-
}
206+
private void initControllerAdviceCaches(ApplicationContext applicationContext) {
207+
180208
if (logger.isInfoEnabled()) {
181209
logger.info("Looking for @ControllerAdvice: " + applicationContext);
182210
}
@@ -354,84 +382,4 @@ public SessionAttributesHandler getSessionAttributesHandler(HandlerMethod handle
354382
(AnnotationUtils.findAnnotation(method, RequestMapping.class) == null) &&
355383
(AnnotationUtils.findAnnotation(method, ModelAttribute.class) != null);
356384

357-
358-
private static class ArgumentResolverRegistrar {
359-
360-
private final List<HandlerMethodArgumentResolver> customResolvers;
361-
362-
private final List<HttpMessageReader<?>> messageReaders;
363-
364-
private final boolean modelAttributeSupported;
365-
366-
private final List<HandlerMethodArgumentResolver> result = new ArrayList<>();
367-
368-
369-
private ArgumentResolverRegistrar(ArgumentResolverConfigurer resolvers,
370-
List<HttpMessageReader<?>> messageReaders, boolean modelAttribute) {
371-
372-
this.customResolvers = resolvers.getCustomResolvers();
373-
this.messageReaders = messageReaders;
374-
this.modelAttributeSupported = modelAttribute;
375-
}
376-
377-
378-
public void add(HandlerMethodArgumentResolver resolver) {
379-
this.result.add(resolver);
380-
}
381-
382-
public void addIfRequestBody(Function<List<HttpMessageReader<?>>, HandlerMethodArgumentResolver> function) {
383-
if (!CollectionUtils.isEmpty(this.messageReaders)) {
384-
add(function.apply(this.messageReaders));
385-
}
386-
}
387-
388-
public void addIfModelAttribute(Supplier<HandlerMethodArgumentResolver> supplier) {
389-
if (this.modelAttributeSupported) {
390-
add(supplier.get());
391-
}
392-
}
393-
394-
public void addCustomResolvers() {
395-
this.customResolvers.forEach(this::add);
396-
}
397-
398-
399-
public List<HandlerMethodArgumentResolver> getResolvers() {
400-
return this.result;
401-
}
402-
403-
public List<SyncHandlerMethodArgumentResolver> getSyncResolvers() {
404-
return this.result.stream()
405-
.filter(resolver -> resolver instanceof SyncHandlerMethodArgumentResolver)
406-
.map(resolver -> (SyncHandlerMethodArgumentResolver) resolver)
407-
.collect(Collectors.toList());
408-
}
409-
410-
public static Builder configurer(ArgumentResolverConfigurer configurer) {
411-
return new Builder(configurer);
412-
}
413-
414-
415-
public static class Builder {
416-
417-
private final ArgumentResolverConfigurer resolvers;
418-
419-
public Builder(ArgumentResolverConfigurer configurer) {
420-
this.resolvers = configurer;
421-
}
422-
423-
public ArgumentResolverRegistrar fullSupport(List<HttpMessageReader<?>> httpMessageReaders) {
424-
return new ArgumentResolverRegistrar(this.resolvers, httpMessageReaders, true);
425-
}
426-
427-
public ArgumentResolverRegistrar modelAttributeSupport() {
428-
return new ArgumentResolverRegistrar(this.resolvers, Collections.emptyList(), true);
429-
}
430-
431-
public ArgumentResolverRegistrar basic() {
432-
return new ArgumentResolverRegistrar(this.resolvers, Collections.emptyList(), false);
433-
}
434-
}
435-
}
436-
437385
}

spring-webflux/src/main/java/org/springframework/web/reactive/result/method/annotation/RequestMappingHandlerAdapter.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,7 +169,7 @@ public void afterPropertiesSet() throws Exception {
169169
}
170170

171171
this.methodResolver = new ControllerMethodResolver(this.argumentResolverConfigurer,
172-
this.messageReaders, this.reactiveAdapterRegistry, this.applicationContext);
172+
this.reactiveAdapterRegistry, this.applicationContext, this.messageReaders);
173173

174174
this.modelInitializer = new ModelInitializer(this.methodResolver, this.reactiveAdapterRegistry);
175175
}

spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ControllerMethodResolverTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ public void setUp() throws Exception {
7676
applicationContext.refresh();
7777

7878
this.methodResolver = new ControllerMethodResolver(
79-
resolvers, codecs.getReaders(), ReactiveAdapterRegistry.getSharedInstance(), applicationContext);
79+
resolvers, ReactiveAdapterRegistry.getSharedInstance(), applicationContext, codecs.getReaders());
8080

8181
Method method = ResolvableMethod.on(TestController.class).mockCall(TestController::handle).method();
8282
this.handlerMethod = new HandlerMethod(new TestController(), method);

spring-webflux/src/test/java/org/springframework/web/reactive/result/method/annotation/ModelInitializerTests.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ public void setUp() throws Exception {
7979
resolverConfigurer.addCustomResolver(new ModelArgumentResolver(adapterRegistry));
8080

8181
ControllerMethodResolver methodResolver = new ControllerMethodResolver(
82-
resolverConfigurer, Collections.emptyList(), adapterRegistry, new StaticApplicationContext());
82+
resolverConfigurer, adapterRegistry, new StaticApplicationContext(), Collections.emptyList());
8383

8484
this.modelInitializer = new ModelInitializer(methodResolver, adapterRegistry);
8585
}

0 commit comments

Comments
 (0)