Spring MVC基本原理

本文详细介绍了SpringMVC的工作原理,包括其内部架构、请求处理流程以及如何通过DispatcherServlet进行请求分发。从HttpServletBean到DispatcherServlet,层层剖析SpringMVC的核心组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

        SpringMVC是Spring的一个后续产品,其实就是spring在原有基础上,又提供了web应用的MVC模块,可以简单的把SpringMVC理解为是Spring的一个模块(类似AOP,IOC这样的模块),网络上经常会说SpringMVC和Spring无缝集成,其实SpringMVC就Spring的一个子模块,所以根本不需要同Spring进行整合。

第一:工作原理


     1)客户端发出一个http请求给web服务器,web服务器对http请求进行解析,如果匹配DispatcherServlet的请求映射路径(在web.xml中指定),web容器将请求转交给DispatcherServlet。

     2)DipatcherServlet接收到这个请求之后将根据请求的信息(包括URL、Http方法、请求报文头和请求参数Cookie等)以及HandlerMapping的配置找到处理请求的处理器(Handler)。

      3)DispatcherServlet根据HandlerMapping找到对应的Handler,将处理权交给Handler(Handler将具体的处理进行封装),再由具体的HandlerAdapter对Handler进行具体的调用。

    4)Handler对数据处理完成以后将返回一个ModelAndView()对象给DispatcherServlet。

    5)Handler返回的ModelAndView()只是一个逻辑视图并不是一个正式的视图,DispatcherSevlet通过ViewResolver将逻辑视图转化为真正的视图View。

    6)Dispatcher通过model解析出ModelAndView()中的参数进行解析最终展现出完整的view并返回给客户端。

第二:Spring MVC的创建过程

1HttpServletBean
过程:在HttpServletBeaninit中,首先进行配置参数使用BeanWrapper设置到DispatcherServlet的相关属性,然后调用模板的方法initServletBean,子类就通过这个方法初始化。
2)FramworkServlet

// org.springframework.web.servlet.FrameworkServlet
	protected final voidinitServletBean() throws ServletException {
		getServletContext().log(
				"InitializingSpring FrameworkServlet '" + getServletName()
						+ "'");
		if (this.logger.isInfoEnabled()) {
			this.logger.info("FrameworkServlet'" + getServletName()
					+ "': initialization started");
		}
		long startTime = System.currentTimeMillis();
		try {
			this.webApplicationContext = initWebApplicationContext();
			initFrameworkServlet();
		} catch (ServletException ex) {
			this.logger.error("Contextinitialization failed", ex);
			throw ex;
		} catch (RuntimeException ex) {
			this.logger.error("Contextinitialization failed", ex);
			throw ex;
		}
		if (this.logger.isInfoEnabled()) {
			long elapsedTime = System.currentTimeMillis() - startTime;
			this.logger.info("FrameworkServlet'" + getServletName()
					+ "': initialization completed in " + elapsedTime + " ms");
		}
	}
过程:初始化WebApplicationContext,初始化FramerworkServlet,而且initFramerworkServlet发法是模板的方法,子类可以覆盖然后在里面做一些初始化的工作,但是子类并没有使用它。
initWebApplicationContext
方法做的三件事:
A
:获取spring的根容器(rootContext)。
B:
设置webApplicationContext并根据情况调用onRefresh方法。
C
:将webApplicationContext设置到ServletContext中。

3DispatcherServlet

// org.springframework.web.servlet.DispathcherServlet
protected voidonRefresh(ApplicationContext context)
  {
    initStrategies(context);
  }
  protected voidinitStrategies(ApplicationContext context)
  {
    initMultipartResolver(context);
    initLocaleResolver(context);
    initThemeResolver(context);
    initHandlerMappings(context);
    initHandlerAdapters(context);
    initHandlerExceptionResolvers(context);
    initRequestToViewNameTranslator(context);
    initViewResolvers(context);
    initFlashMapManager(context);
  }
主要作用:初始化9大组件。
总结:

      SpringMVCServlet一共有三个层次,分别是HttpServletBeanFrameworkServletDisPatcherServletHttpServletBean直接继承自java中的HttpServlet,其作用是将Servlet中配置参数设置到相应的属性,FrameworkServlet初始化WebApplicationContextDisPatcherServlet初始化自身的9个组件。九大组件为HandlerMapping

HandlerAdapterHandlerExceptionResolverViewResolverRequestToViewNameTranslatorLocalResolverThemeResolverMultipartResolverFlashMapManager)。

第三:Spring MVC请求处理

1HttpServletBean
  主要参与创建工作,并没有涉及到请求的处理。
2
FrameworkServlet
  在FrameworkServlet中重写了servicedoGetdoPostdoDeletedoOptionsdoTrace方法。

protected final void processRequest(HttpServletRequestrequest, HttpServletResponse response)
    throwsServletException, IOException
  {
    long startTime =System.currentTimeMillis();
    ThrowablefailureCause = null;
    LocaleContextpreviousLocaleContext = LocaleContextHolder.getLocaleContext();
    LocaleContextlocaleContext = buildLocaleContext(request);
    RequestAttributespreviousAttributes = RequestContextHolder.getRequestAttributes();
    ServletRequestAttributesrequestAttributes = buildRequestAttributes(request, response,previousAttributes);
    WebAsyncManagerasyncManager = WebAsyncUtils.getAsyncManager(request);
   asyncManager.registerCallableInterceptor(FrameworkServlet.class.getName(),new RequestBindingInterceptor(null));
   initContextHolders(request, localeContext, requestAttributes);
    try
    {
     doService(request, response);
    }
    catch(ServletException ex) {
      failureCause =ex;
      throw ex;
    }
    catch (IOExceptionex) {
      failureCause =ex;
      throw ex;
    }
    catch (Throwableex) {
      failureCause =ex;
      throw newNestedServletException("Request processing failed", ex);
    }
    finally
    {
     resetContextHolders(request, previousLocaleContext, previousAttributes);
      if(requestAttributes != null) {
       requestAttributes.requestCompleted();
      }
      if(this.logger.isDebugEnabled()) {
        if(failureCause != null) {
          this.logger.debug("Could not completerequest", failureCause);
        }
        else if(asyncManager.isConcurrentHandlingStarted()) {
         this.logger.debug("Leaving response open for concurrentprocessing");
        }
        else {
          this.logger.debug("Successfullycompleted request");
        }
      }
     publishRequestHandledEvent(request, startTime, failureCause);
    }
  }

 processRequest主要做2件事:
    A:对LocaleContext和RequestAttributes的设置及恢复。
   B:处理完后发布ServletRequestHandledEvent
3)DispatcherServlet
DispatcherServlet是SpringMVC最核心的类,整个处理过程的顶层设计都在这里。
doDispatch方法:

A:根据request找到Handler。

B:根据Handler找到对应的HandlerAdapter。

C:用HandlerAdpter处理Handler。

D:调用processDispatchResult方法处理上面处理过的结果。
Handler:处理器。
HandlerMapping:用来查找Handler的,在SpringMVC中会处理很多请求,每一请求都需要一个Handler来处理,具体接收到一个请求后使用哪一个Handler来处理,这就是HandlerMapping要做的处理。
HandlerAdpter:适配器,在SpringMVC中的Handler可以使任意形式,只要能处理请求就OK,但是Servlet需要处理的方法的结构却是固定的,都是以request和response为参数的方法。怎么让固定的Servlet处理方法调用灵活的Handler来处理这就是HandlerAdapter要做的事情。
Handler是用来干活的工具,HandlerMapping用于根据需要干的活找到相应的工具,HandlerAdapter是使用工具干活的人。
总结:

         HttpServletBean:没有参与实际的请求处理中,FrameworkServlet:将不同的类型的请求结合到了processRequest方法同意处理,processRequest做3件事:

                     A:调用doService模板的方法处理请求。

                     B:将当前请求的LocaleContext和ServletRequestAtrributes在处理请求前设置到了LocalContrextHolder和RequestContextHolder,并将请求处理完成后恢复。

                     C:请求处理完成后发布了ServletRequestHandledEvent消息。
       DispatcherServlet:doService方法给request设置了一些属性,并将请求交给doDispatch方法具体处理。











  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值