Support custom controller method argument resolvers

Closes gh-603
This commit is contained in:
rstoyanchev
2023-03-09 13:32:42 +00:00
parent f23784234a
commit 0f9581d99c
2 changed files with 73 additions and 0 deletions

View File

@@ -18,6 +18,7 @@ package org.springframework.graphql.data.method.annotation.support;
import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
@@ -121,6 +122,8 @@ public class AnnotatedControllerConfigurer
private final FormattingConversionService conversionService = new DefaultFormattingConversionService();
private final List<HandlerMethodArgumentResolver> customArgumentResolvers = new ArrayList<>(8);
@Nullable
private HandlerMethodArgumentResolverComposite argumentResolvers;
@@ -147,6 +150,18 @@ public class AnnotatedControllerConfigurer
registrar.registerFormatters(this.conversionService);
}
/**
* Add {@link HandlerMethodArgumentResolver}'s for custom controller method
* arguments. Such custom resolvers are ordered after built-in resolvers
* except for {@link SourceMethodArgumentResolver}, which is always last.
*
* @param resolvers the resolvers to add.
* @since 1.2
*/
public void setCustomArgumentResolver(List<HandlerMethodArgumentResolver> resolvers) {
this.customArgumentResolvers.addAll(resolvers);
}
HandlerMethodArgumentResolverComposite getArgumentResolvers() {
Assert.notNull(this.argumentResolvers,
"HandlerMethodArgumentResolverComposite is not yet initialized, was afterPropertiesSet called?");
@@ -243,6 +258,8 @@ public class AnnotatedControllerConfigurer
resolvers.addResolver(new ContinuationHandlerMethodArgumentResolver());
}
this.customArgumentResolvers.forEach(resolvers::addResolver);
// This works as a fallback, after all other resolvers
resolvers.addResolver(new SourceMethodArgumentResolver());

View File

@@ -0,0 +1,56 @@
/*
* Copyright 2002-2023 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.graphql.data.method.annotation.support;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.Test;
import org.springframework.context.support.StaticApplicationContext;
import org.springframework.graphql.data.method.HandlerMethodArgumentResolver;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
/**
* Unit tests for {@link AnnotatedControllerConfigurer}.
*
* @author Rossen Stoyanchev
* @since 1.2
*/
public class AnnotatedControllerConfigurerTests {
@Test
void customArgumentResolvers() {
HandlerMethodArgumentResolver customResolver1 = mock(HandlerMethodArgumentResolver.class);
HandlerMethodArgumentResolver customResolver2 = mock(HandlerMethodArgumentResolver.class);
AnnotatedControllerConfigurer configurer = new AnnotatedControllerConfigurer();
configurer.setCustomArgumentResolver(Collections.singletonList(customResolver1));
configurer.setCustomArgumentResolver(Collections.singletonList(customResolver2));
configurer.setApplicationContext(new StaticApplicationContext());
configurer.afterPropertiesSet();
List<HandlerMethodArgumentResolver> resolvers = configurer.getArgumentResolvers().getResolvers();
int size = resolvers.size();
assertThat(resolvers).element(size -1).isInstanceOf(SourceMethodArgumentResolver.class);
assertThat(resolvers).element(size -2).isSameAs(customResolver2);
assertThat(resolvers).element(size -3).isSameAs(customResolver1);
}
}