Laplie opened SPR-17340 and commented
Spring argument resolvers are listed first in
RequestMappingHandlerAdapter.getDefaultArgumentResolvers()
As a result, the built-in argument resolvers always have precedence. In a controller method such as:
@PostMapping("/foo")
public String doSomething(@MyCustomAnnotation Map<String, Object> argument)
Where "@MyCustomAnnotation
" triggers a custom argument resolver, the custom argument resolver is NEVER used because Spring has a built-in resolver for Map.class
There are 2 possible simple solutions I can think of to this problem:
1. Respect the @Order
annotation on method resolvers and sort the resolver list
2. Put the custom method resolvers BEFORE the builtin method resolvers.
In the meantime, the workaround that I have to use is not using a Map for my argument
Affects: 5.0.6
Comment From: spring-projects-issues
Rossen Stoyanchev commented
This is by design and expected behavior. Moving custom resolvers to the top can lead to unexpected side effects.
The actual behavior is that custom resolvers are sandwiched between built-in ones and the ones that "catch-all" ones that make default assumptions. That means as long as you're using a custom type or custom annotation, it should work just fine.
Which resolver is actually trying to process your argument? I would expect none of the resolvers before the custom resolvers to do that, so it should just work.
Comment From: spring-projects-issues
Laplie commented
org.springframework.web.method.annotation.MapMethodProcessor
is the specific one giving me a problem. I can't use my annotation-based resolver on any Maps because that argument resolver gets chosen first.
I don't see how moving the custom argument resolvers to the beginning would cause any issues:
public boolean supportsParameter(MethodParameter parameter)
ensures that any custom argument resolver only gets used when the developer wants it to. I think in the general case, when people are using custom annotations or custom classes they want their resolvers to take precedence.
Comment From: spring-projects-issues
Rossen Stoyanchev commented
I don't recall the specific issues we ran into. It's been so long since this behavior was established. Generally a custom resolver would have to use a custom annotation or a custom type to avoid clashes, in which case it should make no difference. A change of behavior in terms of ordering is not an option at this point.
To address the specific issue you have, MapMethodProcessor
is a bit too aggressive with a general type like Map
. I can update it to check for the absence of any annotations, which is a strong indication it isn't the model that needs to be injected.