自定义HandlerMethodArgumentResolver如何注册到springmvc框架里的

目录

1.DEBUG 注册代码

1.1 WebMvcConfigurerComposite

1.2 DelegatingWebMvcConfiguration

 1.3 AutowiredAnnotationBeanPostProcessor

2.DEBUG调用代码

2.1 this.argumentResolvers


日常工作开发中,总有一些参数,在未传参数时,需要自定义一些参数。

自定义HandlerMethodArgumentResolver如何注册到springmvc框架里的_第1张图片

 比如

@DefaultValueIfNull("1000")

未传值时,默认加1000,用字符串是因为以后想要匹配更多类型。

这时候需要定义一个 HandlerMethodArgumentResolver 

@Component
public class DefaultValueIfNullResolver  implements HandlerMethodArgumentResolver {

    /**
     * 对参数进行默认操作,如果为空值,那么就需要进行特殊操作了
     **/
    private RequestParamMethodArgumentResolver argumentResolver = new RequestParamMethodArgumentResolver(false);

    /**
     * 是否有这个注解
     * @author      
     * @date        2022-12-05 17:47
     **/
    @Override
    public boolean supportsParameter(MethodParameter parameter) {
        return parameter.hasParameterAnnotation(DefaultValueIfNull.class);
    }

    @Override
    public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
        // 1. 获取到 request 对象
        HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
        String name = parameter.getParameter().getName();
        // 2.

        // 得到 DefaultValueIfNull 注解,对注解进行分析,然后操作
        DefaultValueIfNull defaultValueIfNull = parameter.getParameterAnnotation(DefaultValueIfNull.class);

        /** 获取是什么类型的属性 **/
        Class type1 = parameter.getParameter().getType();
        String value = defaultValueIfNull.value();
        Class type = defaultValueIfNull.type();



        return null;
    }
}

注意,上面代码并没有完成,只是作为示例。

这时候就有一个疑问,这个自定义的resolver是如何添加到spring mvc框架里的。

当然,我们需要进行配置。

@Configuration
public class WebMvcConfig implements WebMvcConfigurer {

    @Autowired
    private DefaultValueIfNullResolver resolver;

    @Override
    public void addArgumentResolvers(List resolvers) {
        resolvers.add(resolver);
    }
}

1.DEBUG 注册代码

自定义HandlerMethodArgumentResolver如何注册到springmvc框架里的_第2张图片

 

1.1 WebMvcConfigurerComposite

 类路径 

org.springframework.web.servlet.config.annotation.WebMvcConfigurerComposite

自定义HandlerMethodArgumentResolver如何注册到springmvc框架里的_第3张图片
将 WebMvcConfigurer的各种实现类,放到 delegates里

继续向下

1.2 DelegatingWebMvcConfiguration

org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration

可以看到,这里是使用Spring容器进行操作的

自定义HandlerMethodArgumentResolver如何注册到springmvc框架里的_第4张图片 

 1.3 AutowiredAnnotationBeanPostProcessor

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor

自定义HandlerMethodArgumentResolver如何注册到springmvc框架里的_第5张图片

这个类的的结构图,参看下列 

自定义HandlerMethodArgumentResolver如何注册到springmvc框架里的_第6张图片

 AutowiredAnnotationBeanPostProcessor实现了BeanPostProcessor接口,当 Spring 容器启动时,AutowiredAnnotationBeanPostProcessor 将扫描 Spring 容器中所有 Bean,当发现 Bean 中拥有@Autowired 注解时就找到和其匹配(默认按类型匹配)的 Bean,并注入到对应的地方中去。先来看下buildAutowiringMetadata方法

这是正常的生命周期操作。

到了第一步,就知道已经注册到容器里,但是自定义resolver是何时调用的呢 ?

那么需要关注

DelegatingWebMvcConfiguration

2.DEBUG调用代码

org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport

在 WebMvcConfigurationSupport 这个配置类,可以看到 

RequestMappingHandlerAdapter

这个方法,返回了一个handlerAdapter,在这里进行了操作。

自定义HandlerMethodArgumentResolver如何注册到springmvc框架里的_第7张图片

2.1 this.argumentResolvers

进入这个方法,可以看到初始化的操作。

自定义HandlerMethodArgumentResolver如何注册到springmvc框架里的_第8张图片

 下面进入  addArgumentResolvers

自定义HandlerMethodArgumentResolver如何注册到springmvc框架里的_第9张图片

这个 this.configurers 在 [ 1.2 DelegatingWebMvcConfiguration ]

看类型继承,可以看到

DelegatingWebMvcConfiguration 的大部分配置都是在父类 WebMvcConfigurationSupport 里进行定义了,这也是典型的模板方法。

我们继续进入到

addArgumentResolvers

内部方法里。

关于  this.delegates 查看 1.1 WebMvcConfigurerComposite

自定义HandlerMethodArgumentResolver如何注册到springmvc框架里的_第10张图片

 这里实际上是调用了WebMvcConfigurer的实现类的  addArgumentResolvers方法。

也就是自定义WebMvcConfig里面的代码。

List resolvers  具体看 2.1 this.argumentResolvers

自定义HandlerMethodArgumentResolver如何注册到springmvc框架里的_第11张图片

 最终 

 自定义HandlerMethodArgumentResolver如何注册到springmvc框架里的_第12张图片

 

 

 

 

你可能感兴趣的:(Springboot,java,java)