SpringMVC 请求响应过程讲解

在这里spring 的bean初始化与注入在这里不在复述,今天就只讲 mvc请求响应的过程。

首先我们确定mvc请求的一个入口,dispatcherServlet 的doservice 方法,这里只讲一些比较重要的一些处理。设置request一些属性,然后调用doDispatch(request, response);在此方法中有以下步骤

1.获取请求的相关处理器:getHandler(processedRequest);

 */
    protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        for (HandlerMapping hm : this.handlerMappings) {
            if (logger.isTraceEnabled()) {
                logger.trace(
                        "Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
            }
            HandlerExecutionChain handler = hm.getHandler(request);
            if (handler != null) {
                return handler;
            }
        }
        return null;

@Override
    public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        Object handler = getHandlerInternal(request); //主要是requestmapping 与handlerMethod 映射关系
        if (handler == null) {
            handler = getDefaultHandler();
        }
        if (handler == null) {
            return null;
        }
        // Bean name or resolved handler?
        if (handler instanceof String) {
            String handlerName = (String) handler;
            handler = getApplicationContext().getBean(handlerName);
        }
        return getHandlerExecutionChain(handler, request);
    }

1.首先我们获取通过request获取请求路径,然后进行路径组装,比如我请求路径http://localhost:7001/UserProject/login/add 红色部分就是其请求路径

2.获取到请求路径调用lookupHandlerMethod,首先根据路径从this.urlMap.get(lookupPath)得到一个path的一个匹配字符串,用于mapping与handlermethod映射的参数,(urlMapping是在AbstractHandlerMethodMapping在初bean始化时进行初始化因为实现了Initializingean  调用public void afterPropertiesSet() {
        initHandlerMethods();
    }

protected void initHandlerMethods() {
        if (logger.isDebugEnabled()) {
            logger.debug("Looking for request mappings in application context: " + getApplicationContext());
        }

        String[] beanNames = (this.detectHandlerMethodsInAncestorContexts ?
                BeanFactoryUtils.beanNamesForTypeIncludingAncestors(getApplicationContext(), Object.class) :
                getApplicationContext().getBeanNamesForType(Object.class));

        for (String beanName : beanNames) {
            if (!beanName.startsWith(SCOPED_TARGET_NAME_PREFIX) &&
                    isHandler(getApplicationContext().getType(beanName))){//此方法判断我们过滤的控制器类是否有controller,requestMapping 注解
                detectHandlerMethods(beanName);//如果存在此注解,则进行封装,设置方法与请求类的一个映射,然后将handler,mapping,method 进行处理,将其满足条件的处理类与mapping封装到urlmapping容器中this.urlMap.add(pattern, mapping);
            }
        }
        handlerMethodsInitialized(getHandlerMethods());
    }

4.然后获取request的相应的adapter HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

5.通过前置applyPreHandle

6.调用处理请求方法mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

调用invokeHandleMethod方法中invokeForRequest  通过策略模式处理请求参数的处理类,根据策略模式调用不同的返回参数处理returnValueHandlers.handleReturnValue()

7.封装modelandview 并且根据参数类型返回页面还是数据,调用requestdispatcher的forward方法,如果为director则进行封装转发

8.调用后置处理器进行资源释放等操作。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值