zoukankan      html  css  js  c++  java
  • springmvc 参数解析绑定原理

     handlerMethodArgumentResolver:方法参数解析器接口,这个接口是springmvc参数解析绑定的核心接口。不同的参数类型绑定都是通过实行这个接口来实现。也可以通过实现这个接口来自定义参数解析器。这个接口有如下两个方法:

    public interface HandlerMethodArgumentResolver{
    
       //该解析器是否支持parameter参数的解析         
       boolean supportsParameter (MethodParameter parameter);              
    
      //将方法参数从给定请求(webRequest)解析为参数值并返回
       Object resolveArgument(MethodParameter parameter,
                        ModelAndViewContainer mavContainer,
                        NativeWebRequest webRequest,
                       WebDataBinderFactory binderFactory) throws Exceptions;
    
    }                

     

    初始化

    RequestMappingHandlerAdapter.java类的afterProperitesSet方法初始化相关方法参数解析器,代码如下:

    public void afterPropertiesSet(){
        if(this.argumentResolvers==null){
           //初始化springmvc默认的方法参数解析器,并添加到argumentResolvers(HandlerMethodArgumentResolverComposite)
          List<HandlerMethodArgumentResolver> resolvers = getDefaultArgumentResolvers():
          this.argumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);          
    
         }
         if(this.initBinderArgumentResolvers==null){
             //初始化springmvc默认的初始化绑定器(@InitBinder)参数解析器,并添加至initBinderArgumentResolvers(HandlerMethosArgumentResolverComposite)
            List<HandlerMethosArgumentResolver> resolvers = getDefaultInitBinderArgumentResolvers();
            this.initBinderArgumentResolvers = new HandlerMethodArgumentResolverComposite().addResolvers(resolvers);   
        } 
        if(this.returnValueHandlers==null){
             //获取默认的方法返回值解析器
           List<HandlerMethodreturnValueHandler> handler = getDefaultReturnValueHandlers();
           this.returnValueHandlers = new HandlerMethodReturnValueHandlerComposite().addHandlers(handlers);
        } 
        initControllerAdviceCache();
    }

     

    现在我们进入getDefaultArgumentResolvers方法,代码如下

    //默认的参数解析,创建了默认的24个参数解析器,并添加至resolvers
    //这里的24个参数解析器都是针对不同的参数类型来解析的
    private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() {
        List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>();
    
        // 基于注解的参数解析器
    
        //一般用于带有@RequestParam注解的简单参数绑定,简单参数比如byte、int、long、double、String以及对应的包装类型
        resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false));
        //用于处理带有@RequestParam注解,且参数类型为Map的解析绑定
        resolvers.add(new RequestParamMapMethodArgumentResolver());
        //一般用于处理带有@PathVariable注解的默认参数绑定
        resolvers.add(new PathVariableMethodArgumentResolver());
        //也是用于带有@PathVariable注解的Map相关参数绑定,后续还有一些默认的参数解析器。后续还有一些参数解析器,我这里都不一一解释了。想具体确认某个参数会交个哪个参数解析器处理,可以通过以下解析器的supportsParameter(MethodParameter parameter)方法得知
        resolvers.add(new PathVariableMapMethodArgumentResolver());
        resolvers.add(new MatrixVariableMethodArgumentResolver());
        resolvers.add(new MatrixVariableMapMethodArgumentResolver());
        resolvers.add(new ServletModelAttributeMethodProcessor(false));
        resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters()));
        resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters()));
        resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory()));
        resolvers.add(new RequestHeaderMapMethodArgumentResolver());
        resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory()));
        resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory()));
    
        // 基于类型的参数解析器
        resolvers.add(new ServletRequestMethodArgumentResolver());
        resolvers.add(new ServletResponseMethodArgumentResolver());
        resolvers.add(new HttpEntityMethodProcessor(getMessageConverters()));
        resolvers.add(new RedirectAttributesMethodArgumentResolver());
        resolvers.add(new ModelMethodProcessor());
        resolvers.add(new MapMethodProcessor());
        resolvers.add(new ErrorsMethodArgumentResolver());
        resolvers.add(new SessionStatusMethodArgumentResolver());
        resolvers.add(new UriComponentsBuilderMethodArgumentResolver());
    
        // Custom arguments
        if (getCustomArgumentResolvers() != null) {
            resolvers.addAll(getCustomArgumentResolvers());
        }

     

    参数解析器添加至HandlerMethodArgumentResolverComposite这个类,它是实现了HandlerMethodArgumentResolver接口。这里运用设计模式的中的composite模式(组合模式),在springmvc中,所有请求的参数解析都是进入HandlerMethodArgumentResolverComposite类来实现的。它有两个成员变量,如下

     

    //它的元素在RequestMappingHandlerAdapter类的afterPropertiesSet方法中被添加,存放的是springmvc默认的一些HandlerMethodArgumentResolver参数解析器
    private final List<HandlerMethodArgumentResolver> argumentResolvers = new LinkedList<HandlerMethodArgument>Resolver();
    //存放已经解析过的参数,已经对应的HandlerMethodAgrumentResolver解析器,加快查找过程
    private final Map<MethodParameter,HandlerMethodArgumentResolver> argumentResolverCache = new ConcurrentHashMap<MethodParameter,HandlerMethodArgumentResolver>(256);

     

     

     

     

     

     

     

    参考资料:https://www.cnblogs.com/w-y-c-m/p/8443892.html

  • 相关阅读:
    zookeeper编译环境搭建
    windows下zookeeper安装并发布成windows服务
    ScheduledThreadPoolExecutor源码
    AbstractExecutorService源码
    FutureTask源码2
    FutureTask源码
    ThreadPoolExecutor源码2
    ThreadPoolExecutor源码1
    二进制转10进制
    Android ANR Waiting because no window has focus问题分析
  • 原文地址:https://www.cnblogs.com/javadongx/p/11568571.html
Copyright © 2011-2022 走看看