面试问烂的SpringMVC执行流程

面试问烂的SpringMVC执行流程

  1. 整体流程图:
    面试问烂的SpringMVC执行流程_第1张图片
  2. 请求发送给web容器后,容器会调用DispatchServlet的doService方法处理请求,处理步骤如下。
  3. 设置属性
// 1. 设置属性
// 设置web应用上下文
request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());
//设置本地解析器
request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);
// 设置主题解析器
request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);
  1. 根据请求的URL,获取对应的处理器执行链-其实就是拦截器和Controller代理对象
// 2. 找 handler 返回执行链
HandlerExecutionChain mappedHandler = getHandler(request);
  1. 获取处理器适配器,采用装饰器模式对处理器进行增强,可以在处理器处理请求前做一些操作。
// 3. 返回 handler 的适配器
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
//处理器适配器的handle方法就是使用handler处理请求
public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object delegate)
            throws IOException, ServletException {
                      // 你可能需要 doSomething.......
            ((MyHandler) delegate).doSomething(request);
            return null;
        }
  1. 循环执行 handler 的 pre 拦截器
    这里的前置拦截器和后置拦截器就是同一个拦截器,只不过前置拦截调用preHandle方法,后置拦截调用postHandle方法,前置拦截从第一个拦截器开始循环
// 4. 循环执行 handler 的 pre 拦截器
for (int i = 0; i < mappedHandler.getInterceptors().length; i++) {
    HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i];
    // pre 拦截器
    if (!interceptor.preHandle(request, response, mappedHandler.getHandler())) {
        return;
    }
}
  1. 使用Handler处理请求,Handler其实就是Controller的代理对象
// 5. 执行真正的 handler,并返回  ModelAndView(Handler 是个代理对象,可能会执行 AOP )
ModelAndView mv = ha.handle(request, response, mappedHandler.getHandler());
  1. 循环执行后置拦截器
// 6. 循环执行 handler 的 post 拦截器
for (int i = mappedHandler.getInterceptors().length - 1; i >=0 ; i--) {
    HandlerInterceptor interceptor = mappedHandler.getInterceptors()[i];
    // post 拦截器
    interceptor.postHandle(request, response, mappedHandler.getHandler());
}
  1. 使用viewResolver解析ModelAndView获得View实例
View view = null;
if (mv.isReference()) {
    // We need to resolve this view name
    // 7. 根据 ModelAndView 信息得到 View 实例
    view = this.viewResolver.resolveViewName(mv.getViewName(), locale);
}
  1. 渲染View实例返回
// 8. 渲染 View 返回
view.render(mv.getModel(), request, response);

你可能感兴趣的:(SpringMVC)