SpringMVC源码解析, 原理解析

SpringMVC原理剖析

SpringMVC框架和Servlet容器具体详细图,周舟

1 初始环境是 tomcat 容器!

    根据你的web.xml 读取配置信息,

2 Tomcat 依赖servlet.jar规范

 ---  Init(config) 初始化配置,配置从web.xml 通过servlet规范读取

 --- Service 请求进行服务

 --- Destory 销毁

3 SpringMVC (Servlet服务) 实现了Servlet规范

    这边重写了init,service,destory

SpringMVC入口在 DispatcherServlet

可以从继承树上找到SpringMVC是Servlet的扩展,

上图是servlet的规范

总结,延续Servlet体系的半封装框架

1.        如何初始化SpringMVC上下文

a)        Init()方法在httpServlet的父类GenericServlet

b)        Destory()方法也在GenericServlet中(如下图所示)

c)        httpServlet只重写了service()

d)        而HttpServletBean中重写了init()方法

HttpServletBean 重写了GenericServlet里面的init()方法而进入了SpringMVC自身上下文初始化

public final void init() throws ServletException{
   if (logger.isDebugEnabled()) {
      logger.debug("Initializing servlet '" + getServletName() + "'");
   }

   // 将Servlet中封装的参数封装到PropertyValues

// requiredProperties:必须的参数数据,如果没有会报异常
   try {

// 这里的getServletContext就是获取web.xml中的
      PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
     // 属性编辑器,控制修改我们的ServletConfig属性

 BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
      // 获取资源加载器

ResourceLoaderresourceLoader = new ServletContextResourceLoader(getServletContext());
      // 注册我们的资源类型

bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader));
      // 初始化属性编辑器对象bw

initBeanWrapper(bw);
      bw.setPropertyValues(pvs, true);
   }
   catch (BeansExceptionex) {
      logger.error("Failed to set bean properties onservlet '" + getServletName()+ "'", ex);
      throw ex;
   }

   // 模板方法, 给我们子类FramworkServlet具体实现了他

// 他用来初始化SpringMvc框架Bean组件Controller 还有九大组件
   initServletBean();

   if (logger.isDebugEnabled()) {
      logger.debug("Servlet '" + getServletName() + "' configured successfully");
   }
}

init这个方法主要调用了(initServletBean()方法),protected修饰, 在FramworkServlet中实现了

// initServletBean方法里主要调用了initWebApplicationContext()方法, 由于SpringMVC的上下文继承了WebApplicationContext

所以这个方法主要是用来刷新和获取上下文, 详情如下

刷新后!! 执行最注重要的onRefresh()

if (!this.refreshEventReceived) {
   // Apparently not a ConfigurableApplicationContext with refresh support:
   // triggering initial onRefresh manually here.
   onRefresh(wac);
}

最终调用了DispatcherServlet的OnRefresh方法, 初始化九大组件

 
 
@Override
protected void onRefresh(ApplicationContext context) {
   initStrategies(context);
}

/**
 * Initialize the strategy objects that this servlet uses.
 * <p>May be overridden in subclasses in order to initialize further strategy objects.
 */
protected void initStrategies(ApplicationContext context) {
   initMultipartResolver(context);
// 本地解析
   initLocaleResolver(context);
// 主题解析
   initThemeResolver(context);
// 映射器组件
   initHandlerMappings(context);
// 初始化适配器
   initHandlerAdapters(context);
// 初始化程序异常解析器
   initHandlerExceptionResolvers(context);
// 
   initRequestToViewNameTranslator(context);
//初始化视图解析器
   initViewResolvers(context);
}


Init完成点done

2.        接受业务请求!

a)        来到HttpServlet这里,寻找service()请求;

public void service(ServletRequest req, ServletResponse res)
throws ServletException, IOException
   {
HttpServletRequest request;
HttpServletResponse    response;

try {
    request = (HttpServletRequest) req;
    response = (HttpServletResponse) res;
} catch (ClassCastException e) {
    throw new ServletException("non-HTTP request or response");
}
service(request, response);
   }

总结:SpringMVC的业务请求流程是重写HttpServlet的service方法中的分派方法(例如doPost())

b)   protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException
   {
String method = req.getMethod();

if (method.equals(METHOD_GET)) {
    long lastModified = getLastModified(req);
    if (lastModified == -1) { 
   // servlet doesn't support if-modified-since, no reason
   // to go through further expensive logic
   doGet(req, resp);
    } else {
   long ifModifiedSince = req.getDateHeader(HEADER_IFMODSINCE);
   if (ifModifiedSince < lastModified) {
       // If the servlet mod time is later, call doGet()
                   // Round down to the nearest second for a proper compare
                   // A ifModifiedSince of -1 will always be less
       maybeSetLastModified(resp, lastModified);
       doGet(req, resp);
   } else {
       resp.setStatus(HttpServletResponse.SC_NOT_MODIFIED);
   }
    }

} else if (method.equals(METHOD_HEAD)) {
    long lastModified = getLastModified(req);
    maybeSetLastModified(resp, lastModified);
    doHead(req, resp);

} else if (method.equals(METHOD_POST)) {
    doPost(req, resp);
    
} else if (method.equals(METHOD_PUT)) {
    doPut(req, resp);  
    
} else if (method.equals(METHOD_DELETE)) {
    doDelete(req, resp);
    
} else if (method.equals(METHOD_OPTIONS)) {
    doOptions(req,resp);
    
} else if (method.equals(METHOD_TRACE)) {
    doTrace(req,resp);
    
} else {
    //
    // Note that this means NO servlet supports whatever
    // method was requested, anywhere on this server.
    //

    String errMsg = lStrings.getString("http.method_not_implemented");
    Object[] errArgs = new Object[1];
    errArgs[0] = method;
    errMsg = MessageFormat.format(errMsg, errArgs);
    
    resp.sendError(HttpServletResponse.SC_NOT_IMPLEMENTED, errMsg);
}
   }

c)        分类方法在FramworkServlet中重写了, 主要调用了processRequest(request,response)方法

@Override
protected final void doPost(HttpServletRequest request, HttpServletResponse response)
      throws ServletException, IOException {

   processRequest(request, response);
}

d)       真正执行的是doService()方法, 他在DispatcherServlet里重写

try {
   doService(request, response);
}

e)        doService()方法中,快照备份后, 组装一些组件,和解析器执行doDispatch(request,response);方法

/**


 /* 
*处理实际调度到处理程序。 
* <p>处理程序将通过按顺序应用servlet的HandlerMappings来获得。 
HandlerAdapter将通过查询Servlet的已安装HandlerAdapter获得 *找到支持处理程序类的第一个。 
* <p>所有HTTP方法都由此方法处理。 这取决于HandlerAdapters或Handler
 *自己决定哪些方法可以接受。
@param response current HTTP response
 * @throws Exception in case of any kind of processing failure
 */
 
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
   HttpServletRequest processedRequest = request;
   HandlerExecutionChain mappedHandler = null;
   int interceptorIndex = -1;

   try {
     // 模型视图对象
      ModelAndView mv;
      boolean errorView = false;

      try {
            // 检查是否是上传 请求
         processedRequest = checkMultipart(request);

         // 根据请求找到handler.
         mappedHandler = getHandler(processedRequest, false);
         if (mappedHandler == null || mappedHandler.getHandler() == null) {
            noHandlerFound(processedRequest, response);
            return;
         }

         // 根据HandlerAdapter 找到HandlerExecutionChain处理执行链来确定handler
         HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

               // 处理GET/HEAD请求的LastModified
         String method = request.getMethod();
         boolean isGet = "GET".equals(method);
         if (isGet || "HEAD".equals(method)) {
            long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
            // 查看是否有缓存
            if (logger.isDebugEnabled()) {
               String requestUri = urlPathHelper.getRequestUri(request);
               logger.debug("Last-Modified value for [" + requestUri + "] is: " + lastModified);
            }
            if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
               return;
            }
         }

         // 执行相应的拦截器的PreHandle
         HandlerInterceptor[] interceptors = mappedHandler.getInterceptors();
         if (interceptors != null) {
            for (int i = 0; i < interceptors.length; i++) {
               HandlerInterceptor interceptor = interceptors[i];
               if (!interceptor.preHandle(processedRequest, response, mappedHandler.getHandler())) {
                  triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
                  return;
               }
               interceptorIndex = i;
            }
         }

         // 执行handle处理请求返回modelAndView
         mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

         // 当view为空(比如Handler返回为void),根据request设置默认的mv
         if (mv != null && !mv.hasView()) {
            mv.setViewName(getDefaultViewName(request));
         }

         // 拦截器后处理, 在modeAndView返回DispatcherServlet前,按照执行链的反顺序操作
         if (interceptors != null) {
            for (int i = interceptors.length - 1; i >= 0; i--) {
               HandlerInterceptor interceptor = interceptors[i];
               interceptor.postHandle(processedRequest, response, mappedHandler.getHandler(), mv);
            }
         }
      }
      catch (ModelAndViewDefiningException ex) {
         logger.debug("ModelAndViewDefiningException encountered", ex);
         mv = ex.getModelAndView();
      }
      catch (Exception ex) {
         Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);
         mv = processHandlerException(processedRequest, response, handler, ex);
         errorView = (mv != null);
      }

      // Did the handler return a view to render?
      if (mv != null && !mv.wasCleared()) {
         render(mv, processedRequest, response);
         if (errorView) {
            WebUtils.clearErrorRequestAttributes(request);
         }
      }
      else {
         if (logger.isDebugEnabled()) {
            logger.debug("Null ModelAndView returned to DispatcherServlet with name '" + getServletName() +
                  "': assuming HandlerAdapter completed request handling");
         }
      }

      // 处理完成后的回调! 回调
      triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, null);
   }

   catch (Exception ex) {
      // Trigger after-completion for thrown exception.
      triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
      throw ex;
   }
   catch (Error err) {
      ServletException ex = new NestedServletException("Handler processing failed", err);
      // Trigger after-completion for thrown exception.
      triggerAfterCompletion(mappedHandler, interceptorIndex, processedRequest, response, ex);
      throw ex;
   }

   finally {
      // Clean up any resources used by a multipart request.
      if (processedRequest != request) {
         cleanupMultipart(processedRequest);
      }
   }
}

f)         拦截器的三种方法全部执行到

3.         

4.         

5.         


猜你喜欢

转载自blog.csdn.net/weixin_38399962/article/details/80245139
今日推荐