DispatcherServlet源码剖析

本文解析了Spring MVC中DispatcherServlet的工作原理,包括Bean初始化过程及请求处理流程。重点关注DispatcherServlet如何初始化关键组件如HandlerMappings和HandlerAdapters,并详细介绍了doDispatch方法如何处理请求。

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

    DispatcherServlet也是一个Servlet,它是间接继承于HttpServlet的。具体的继承关系为DispatcherServlet->FrameworkServlet->HttpServletBean->HttpServlet,HttpServlet就是我们在不用框架时所使用的Servlet,它提供了doGet,doPost,doPut,doDelete,doPotions,doTrace,service这几个方法执行前台发送过来的请求。我们在使用springmvc时,最需要关心的就两点,一是各种Resolver和HandlerMapping、HandlerAdapter等Bean的初始化操作,另一点就是springmvc请求发送执行的过程。首先来看看在DispataherServlet中的Bean的初始化。

	/**
	 * This implementation calls {@link #initStrategies}.
	 */
	@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);
		initFlashMapManager(context);
	}

    以上就是DispatcherServlet类中的Bean初始化方法,统一在onRefresh中初始化所有的Bean,主要被初始化的Bean类型有MultipartResolver,LocaleResolver,ThemeResolver,HandlerMappings,HandlerAdapters,HandlerExceptionResolvers,RequestToViewNameTranslator,ViewResolvers,FlashMapManager,这些都是可以在springmvc-servlet.xml中配置依赖注入的。

    执行前端发送过来的请求的过程主要发生在DispatcherServlet类的doDispatcher方法中,这个方法由doService方法调用,doService由父类FrameworkServlet的processRequest方法调用,processRequest直接由HttpServlet方法的几个请求执行方法调用。

	/**
	 * Process the actual dispatching to the handler.
	 * <p>The handler will be obtained by applying the servlet's HandlerMappings in order.
	 * The HandlerAdapter will be obtained by querying the servlet's installed HandlerAdapters
	 * to find the first that supports the handler class.
	 * <p>All HTTP methods are handled by this method. It's up to HandlerAdapters or handlers
	 * themselves to decide which methods are acceptable.
	 * @param request current HTTP request
	 * @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;
		boolean multipartRequestParsed = false;

		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);

		try {
			ModelAndView mv = null;
			Exception dispatchException = null;

			try {
				......

				// Determine handler for the current request.
				mappedHandler = getHandler(processedRequest);
				......

				// Determine handler adapter for the current request.
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

				......

				// Actually invoke the handler.
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

				......
			}
			catch (Exception ex) {
				dispatchException = ex;
			}
			processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
		}
		catch (Exception ex) {
			......
		}
		catch (Error err) {
			......		}
		finally {
			......
		}
	}
    这是我省略了部分代码,只留下了Handler匹配映射、controller执行、异常处理等主要执行流程方法。在内部try-catch语句中,分别调用了getHandler方法和getHandlerAdapter方法执行Handler匹配映射,分别找到请求所对应的Controller类和Controller类中的具体执行方法,然后通过执行方法对应的HandlerAdapter来执行这个请求的处理过程,如果处理过程中抛出了异常,则在catch中记录下该异常,最终执行processsDispatchResult来处理执行结果,如果dispatchException不为空,也就是执行请求处理过程中出现了异常,则会在processDispatchResult中调用异常处理方法。一次doDispatch过程即一次请求过程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值