Search code examples
springspring-bootspring-webfluxspring-config

How to Inject custom method argument in Spring WebFlux using HandlerMethodArgumentResolver?


I want to create an custom method argument Resolver using Spring WebFlux. I am following link but its seem to be not working.

I am able to create the custom argument resolver using WebMvc.

import org.springframework.web.reactive.result.method.HandlerMethodArgumentResolver;

public class MyContextArgumentResolver implements HandlerMethodArgumentResolver {

@Override
    public boolean supportsParameter(MethodParameter parameter) {
        return MyCustomeObject.class.isAssignableFrom(parameter.getParameterType())

   }

@Override
    public Mono<Object> resolveArgument(MethodParameter parameter, BindingContext bindingContext,
            ServerWebExchange exchange) {

.....
return Mono.just(new MyCustomeObject())
}

Please note that i am using HandlerMethodArgumentResolver from .web.reactive. package.

My AutoConfiguration file look like

@Configuration
@ConditionalOnClass(EnableWebFlux.class) // checks that WebFlux is on the class-path
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE)//checks that the app is a reactive web-app
public class RandomWebFluxConfig implements WebFluxConfigurer {

    @Override
    public void configureArgumentResolvers(ArgumentResolverConfigurer configurer) {
MyContextArgumentResolver[] myContextArgumentResolverArray = {contextArgumentResolver()};
        configurer.addCustomResolver(myContextArgumentResolverArray );
    }

    @Bean
    public MyContextArgumentResolver contextArgumentResolver() {
        return new MyContextArgumentResolver ();
    }

My spring.factories looks like

# Auto Configure
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.XXXX.XXX.XXX.RandomWebFluxConfig

Please note that above configuration is part of the jar which is added in Spring WebFlux Boot project enabled using @EnableWebFlux .


Solution

  • It seems you're conflating two different problems here.

    First, you should make sure that your method argument resolver works in a regular project.

    For that, you need a @Configuration class that implements the relevant method in WebFluxConfigurer. Your code snippet is doing that but with two flaws:

    • Your configuration is using @EnableWebFlux, which is disabling the WebFlux auto-configuration in Spring Boot. You should remove that
    • it seems you're trying to cast a list of MethodArgumentResolver into a single instance and that's probably why things aren't working here. I believe your code snippet could be just:

      configurer.addCustomResolver(contextArgumentResolver());
      

    Now the second part of this question is about setting this up as a Spring Boot auto-configuration. I guess that you'd like WebFlux applications to automatically get that custom argument resolvers if they depend on your library.

    If you want to achieve that, you should first make sure to read up a bit about auto-configurations in the reference documentation. After that, you'll realize that your configuration class is not really an auto-configuration since it will be applied in all cases.

    You should probably add a few conditions on that configuration like:

    @ConditionalOnClass(EnableWebFlux.class) // checks that WebFlux is on the classpath
    @ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.REACTIVE) // checks that the app is a reactive web app