【源码解析】SpringMvc框架的源码解析

SpringMvc框架的源码解析

SpringMVC处理请求的流程源码剖析

  1. 接收请求。DispatcherServlet是一个Servlet,在浏览器输入url,会接收到对应的请求。HttpServlet#service()
  2. 请求分发。DispatcherServlet顾名思义,负责分发的Servlet。核心方法,DispatcherServlet#doDispatch
  3. 根据请求获取HandlerExecutionChain对象。因为handlerMapping有多个类型,我们最常用的是RequestMappingHandlerMapping。执行AbstractHandlerMethodMapping#lookupHandlerMethod,根据request获取到对应的url,根据url从MappingRegistry#pathLookup变量中获取对应的处理器。
    @Nullable
    protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
        if (this.handlerMappings != null) {
            Iterator var2 = this.handlerMappings.iterator();

            while(var2.hasNext()) {
                HandlerMapping mapping = (HandlerMapping)var2.next();
                HandlerExecutionChain handler = mapping.getHandler(request);
                if (handler != null) {
                    return handler;
                }
            }
        }
        return null;
    }

AbstractHandlerMapping#getHandlerExecutionChain,对找到的处理器进行封装。

	protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
		HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
				(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));

		for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
			if (interceptor instanceof MappedInterceptor) {
				MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
				if (mappedInterceptor.matches(request)) {
					chain.addInterceptor(mappedInterceptor.getInterceptor());
				}
			}
			else {
				chain.addInterceptor(interceptor);
			}
		}
		return chain;
	}
  1. 获取处理器适配器。DispatcherServlet#getHandlerAdapter,常见的还是RequestMappingHandlerAdapter。在执行到ServletInvocableHandlerMethod#invokeAndHandle方法中,会对返回值进行处理。this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);。我们接口中常用的json字符串返回用到的返回值处理器是RequestResponseBodyMethodProcessor,当返回类型满足AnnotatedElementUtils.hasAnnotation(returnType.getContainingClass(), ResponseBody.class) || returnType.hasMethodAnnotation(ResponseBody.class);,则会调用RequestResponseBodyMethodProcessor来对返回值处理。
  2. 对处理器进行前置处理,主要执行mappedHandler.applyPreHandle(processedRequest, response)。执行HandlerExecutionChain中的处理器的preHandle方法。
boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {
		for (int i = 0; i < this.interceptorList.size(); i++) {
			HandlerInterceptor interceptor = this.interceptorList.get(i);
			if (!interceptor.preHandle(request, response, this.handler)) {
				triggerAfterCompletion(request, response, null);
				return false;
			}
			this.interceptorIndex = i;
		}
		return true;
	}
  1. 执行处理器。通过获取到的HandlerAdapter,即RequestMappingHandlerAdapter来执行RequestMappingHandlerAdapter#handleInternal。反射调用方法,得到一个ModelAndView对象。
  2. 对处理器进行后置处理,mappedHandler.applyPostHandle(processedRequest, response, mv);。执行HandlerExecutionChain中的处理器的postHandle方法。
  3. 对处理器进行异常处理,triggerAfterCompletion(processedRequest, response, mappedHandler, ex)
  4. 处理分发结果,渲染视图。DispatcherServlet#processDispatchResult。渲染视图,DispatcherServlet#render->AbstractView#render

SpringMvc组件初始化的流程解析

  1. servlet对象初始化,只有在第一次访问的时候执行一次。所以DispatcherServlet的初始化是在应用第一次处理web请求的时候。
  2. DispatcherServlet初始化。执行父类GenericServlet#init()。核心方法是DispatcherServlet#initStrategies
	protected void initStrategies(ApplicationContext context) {
		// 多文件上传的组件
		initMultipartResolver(context);
		// 初始化本地语言环境
		initLocaleResolver(context);
		// 初始化模板处理器
		initThemeResolver(context);
		// 初始化HandlerMapping
		initHandlerMappings(context);
		// 初始化参数适配器
		initHandlerAdapters(context);
		// 初始化异常拦截器
		initHandlerExceptionResolvers(context);
		// 初始化视图预处理器
		initRequestToViewNameTranslator(context);
		// 初始化视图转换器
		initViewResolvers(context);
		// 初始化 FlashMap 管理器
		initFlashMapManager(context);
	}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值