spring mvc 的流程(一)

前戏之寻找HandlerMapping

  1. DispatcherServlet中的onRefresh > initStrategies > initHandlerMappings
  2. HandlerMapping获取策略:
    • 容器中获取所有实现了HandlerMapping接口的实例(默认方式)
    • 容器中获取name为常量HANDLER_MAPPING_BEAN_NAME,类型为HandlerMapping的实例
    • 如果上述执行结束之后handlerMappings依然为null.
      则使用DispatcherServlet.properties中配置的HandlerMapping实现类

前戏之寻找HandlerAdapter

  1. DispatcherServlet中的onRefresh > initStrategies > initHandlerAdapters
  2. HandlerAdapter获取策略:
    • 容器中获取所有实现了HandlerAdapter接口的实例(默认方式)
    • 容器中获取name为常量HANDLER_ADAPTER_BEAN_NAME,类型为HandlerAdapter的实例
    • 如果上述执行结束之后handlerAdapters依然为null.
      则使用DispatcherServlet.properties中配置的HandlerAdapter实现类

请求都去了哪 ?

  1. 当我们从页面或者使用ajax发起了一个请求request.

  2. 根据JavaServlet规范,Request会进入到Servlet里面的doGet或者doPost等方法

  3. Spring框架的DispatcherServlet及其父类,帮我们处理了很多细节.然后就到了下面的流程.

  4. DispatcherServlet中的doDispatch方法为入口

  5. 获取mappedHandler:

    for (HandlerMapping hm : this.handlerMappings) {
        HandlerExecutionChain handler = hm.getHandler(request);
        if (handler != null) {
            return handler;
        }
    }
    return null;
    
  6. 获取HandlerAdapter:

    // Determine handler adapter for the current request.
    HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
    
    .........
    
    for (HandlerAdapter ha : this.handlerAdapters) {
        if (logger.isTraceEnabled()) {
            logger.trace("Testing handler adapter [" + ha + "]");
        }
        if (ha.supports(handler)) {
            return ha;
        }
    }
    throw new ServletException("***")
    
  7. 执行前置方法,譬如前置拦截器之类的

    if (!mappedHandler.applyPreHandle(processedRequest, response)) {
        return;
    }
    
    .........
    
    boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
        if (getInterceptors() != null) {
            for (int i = 0; i < getInterceptors().length; i++) {
                HandlerInterceptor interceptor = getInterceptors()[i];
                if (!interceptor.preHandle(request, response, this.handler)) {
                    triggerAfterCompletion(request, response, null);
                    return false;
                }
                this.interceptorIndex = i;
            }
        }
        return true;
    }
    
  8. 执行实际的action方法

    // Actually invoke the handler.
    mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
    
  9. 执行后置方法,譬如后置拦截器之类的

    applyDefaultViewName(request, mv);
    mappedHandler.applyPostHandle(processedRequest, response, mv);
    
    .........
    
    void applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv) throws Exception {
        if (getInterceptors() == null) {
            return;
        }
        for (int i = getInterceptors().length - 1; i >= 0; i--) {
            HandlerInterceptor interceptor = getInterceptors()[i];
            interceptor.postHandle(request, response, this.handler, mv);
        }
    }
    
  10. 然后是视图渲染转发,如果有异常的话就是异常信息的处理

    processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
    

说好的细节呢

前面我们了解了大致的流程,大方向要搞对.下面就改讨论些细节了.

  1. Spring怎么找到实际调用的方法的
  2. 方法参数是何时解析注入的呢
  3. 我返回的Object是在哪被转换成json字符串的呢

且听下回分解

你可能感兴趣的:(spring mvc 的流程(一))