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


    目录

    1.DEBUG 注册代码

    1.1 WebMvcConfigurerComposite

    1.2 DelegatingWebMvcConfiguration

     1.3 AutowiredAnnotationBeanPostProcessor

    2.DEBUG调用代码

    2.1 this.argumentResolvers


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

     比如

    @DefaultValueIfNull("1000")

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

    这时候需要定义一个 HandlerMethodArgumentResolver 

    1. @Component
    2. public class DefaultValueIfNullResolver implements HandlerMethodArgumentResolver {
    3. /**
    4. * 对参数进行默认操作,如果为空值,那么就需要进行特殊操作了
    5. **/
    6. private RequestParamMethodArgumentResolver argumentResolver = new RequestParamMethodArgumentResolver(false);
    7. /**
    8. * 是否有这个注解
    9. * @author
    10. * @date 2022-12-05 17:47
    11. **/
    12. @Override
    13. public boolean supportsParameter(MethodParameter parameter) {
    14. return parameter.hasParameterAnnotation(DefaultValueIfNull.class);
    15. }
    16. @Override
    17. public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception {
    18. // 1. 获取到 request 对象
    19. HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class);
    20. String name = parameter.getParameter().getName();
    21. // 2.
    22. // 得到 DefaultValueIfNull 注解,对注解进行分析,然后操作
    23. DefaultValueIfNull defaultValueIfNull = parameter.getParameterAnnotation(DefaultValueIfNull.class);
    24. /** 获取是什么类型的属性 **/
    25. Class type1 = parameter.getParameter().getType();
    26. String value = defaultValueIfNull.value();
    27. Class type = defaultValueIfNull.type();
    28. return null;
    29. }
    30. }

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

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

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

    1. @Configuration
    2. public class WebMvcConfig implements WebMvcConfigurer {
    3. @Autowired
    4. private DefaultValueIfNullResolver resolver;
    5. @Override
    6. public void addArgumentResolvers(List resolvers) {
    7. resolvers.add(resolver);
    8. }
    9. }

    1.DEBUG 注册代码

     

    1.1 WebMvcConfigurerComposite

     类路径 

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


    将 WebMvcConfigurer的各种实现类,放到 delegates里

    继续向下

    1.2 DelegatingWebMvcConfiguration

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

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

     

     1.3 AutowiredAnnotationBeanPostProcessor

    org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor

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

    QQ图片20200423112050.png

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

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

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

    那么需要关注

    DelegatingWebMvcConfiguration

    2.DEBUG调用代码

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

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

    RequestMappingHandlerAdapter

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

    2.1 this.argumentResolvers

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

     下面进入  addArgumentResolvers

    这个 this.configurers 在 [ 1.2 DelegatingWebMvcConfiguration ]

    看类型继承,可以看到

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

    我们继续进入到

    addArgumentResolvers

    内部方法里。

    关于  this.delegates 查看 1.1 WebMvcConfigurerComposite

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

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

    List resolvers  具体看 2.1 this.argumentResolvers

     最终 

     

     

     

     

     

  • 相关阅读:
    剑指JUC原理-16.读写锁
    北京大学肖臻老师《区块链技术与应用》公开课笔记:以太坊原理(一):以太坊概述、账户、状态树、交易树和收据树
    Web 安全之 Permissions Policy(权限策略)详解
    Treap 学习笔记
    【Django项目记录:django admin后台将查询结果导出表格】
    HighTec快捷键(Keys)设置位置
    百度地图3D棱柱鼠标事件
    修改 Git 已经提交记录的 用户名 和邮箱
    软件设计模式系列之七——原型模式
    【javaEE】多线程初阶(Part4 volatile、wait、notify)
  • 原文地址:https://blog.csdn.net/liu538430/article/details/128198975