Skip to content

Commit

Permalink
Support custom controller method argument resolvers
Browse files Browse the repository at this point in the history
Closes gh-603
  • Loading branch information
rstoyanchev committed Mar 9, 2023
1 parent f237842 commit 0f9581d
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
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;
Expand Down Expand Up @@ -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;

Expand All @@ -147,6 +150,18 @@ public void addFormatterRegistrar(FormatterRegistrar registrar) {
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 comment has been minimized.

Copy link
@koenpunt

koenpunt Mar 9, 2023

Contributor

Shouldn't this be setCustomArgumentResolvers? Or maybe even addCustomArgumentResolvers?

This comment has been minimized.

Copy link
@rstoyanchev

rstoyanchev Mar 9, 2023

Author Contributor

Yes indeed. Thanks!

this.customArgumentResolvers.addAll(resolvers);
}

HandlerMethodArgumentResolverComposite getArgumentResolvers() {
Assert.notNull(this.argumentResolvers,
"HandlerMethodArgumentResolverComposite is not yet initialized, was afterPropertiesSet called?");
Expand Down Expand Up @@ -243,6 +258,8 @@ private HandlerMethodArgumentResolverComposite initArgumentResolvers() {
resolvers.addResolver(new ContinuationHandlerMethodArgumentResolver());
}

this.customArgumentResolvers.forEach(resolvers::addResolver);

// This works as a fallback, after all other resolvers
resolvers.addResolver(new SourceMethodArgumentResolver());

Expand Down
Original file line number Diff line number Diff line change
@@ -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);
}

}

0 comments on commit 0f9581d

Please sign in to comment.