【SpringMVC】DispatcherServlet的执行流程源码分析

注:源码中的handler就是要执行的controller的目标方法。

DispatcherServlet#doService
    DispatcherServlet#doDispatch
        //1.返回此请求的HandlerExecutionChain,即得到该请求的处理器链。
        DispatcherServlet#getHandler(HttpServletRequest request)
            //遍历此servlet使用的HandlerMapping列表(eg.RequestMappingHandlerMapping),逐个找能处理该请求的handler,直至找到一个或遍历完
            for (HandlerMapping hm : this.handlerMappings) {
                //查找给定请求的handler,如果未找到特定的handler,则返回默认handler(this.defaultHandler),若还为null就直接return
                AbstractHandlerMapping#getHandler(HttpServletRequest request)
                    //1.查找给定请求的URL路径的handler
                    AbstractHandlerMethodMapping#getHandlerInternal(HttpServletRequest request)
						//获取请求的url
						String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
						//查找该url对应的HandlerMethod
						HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
                    //2.为给定的handler构建一个HandlerExecutionChain(包含有适用的interceptors)
                    AbstractHandlerMapping#getHandlerExecutionChain(Object handler, HttpServletRequest request)
                        //获取请求的url
                        String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
                        //遍历该HandlerMapping的MappedInterceptor集合
						for (MappedInterceptor mappedInterceptor : this.mappedInterceptors) {
							//若是MappedInterceptor类型
							if (interceptor instanceof MappedInterceptor) {
								MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
								//若能匹配到当前请求的url,就将它添加到要返回的chain中
								if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
									chain.addInterceptor(mappedInterceptor.getInterceptor());
								}
							}
							else {
								chain.addInterceptor(interceptor);
							}
						}
                        return chain;
            }
        //2.返回Handler对象,eg.RequestMappingHandler
        HandlerExecutionChain#getHandler()
        //3.确定当前请求的HandlerAdapter(可理解为一个大反射工具),eg.RequestMappingHandlerAdapter
        DispatcherServlet#getHandlerAdapter(Object handler)
			//遍历此servlet使用的HandlerAdapter集合,若找到一个支持该handler的HandlerAdapter就返回它
			for (HandlerAdapter ha : this.handlerAdapters) {
				if (ha.supports(handler)) {
					return ha;
				}
			}
        //4.应用已注册拦截器的preHandle方法
        HandlerExecutionChain#applyPreHandle(HttpServletRequest request, HttpServletResponse response)
            //返回要应用的拦截器数组(按给定顺序)
            HandlerExecutionChain#getInterceptors()
            // 遍历得到的拦截器数组
            for (int i = 0; i < getInterceptors().length; i++) {
                HandlerInterceptor interceptor = getInterceptors()[i];
                //拦截执行程序,在HandlerMapping确定适当的handler对象之后但在HandlerAdapter调用处理程序之前调用
                interceptor.preHandle(request, response, this.handler)
            }
        //5.真正调用handler
        AbstractHandlerMethodAdapter#handle(HttpServletRequest request, HttpServletResponse response, Object handler)
            //使用给定的 handler method 处理请求,返回ModelAndView
            RequestMappingHandlerAdapter#handleInternal(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod)
                //调用 handler method 准备一个ModelAndView,返回这个ModelAndView
                RequestMappingHandlerAdapter#invokeHandlerMethod(HttpServletRequest request, HttpServletResponse response, HandlerMethod handlerMethod)
                    //1.根据handlerMethod,创建WebDataBinderFactory
                    WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
                        //创建一个空的InvocableHandlerMethod集合
                        List<InvocableHandlerMethod> initBinderMethods = new ArrayList<InvocableHandlerMethod>();
                        //填充这个InvocableHandlerMethod集合
                        ...
                        //根据InvocableHandlerMethod集合创建一个WebDataBinderFactory,并返回
                        return createDataBinderFactory(initBinderMethods);
                    //2.根据handlerMethod和binderFactory,创建ModelFactory
                    ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
					//3.根据handlerMethod,创建ServletInvocableHandlerMethod
					ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
					//4.若参数解析器不为null
					if (this.argumentResolvers != null) {
						invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
					}
					//5.若返回值处理器不为null
					if (this.returnValueHandlers != null) {
						invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
					}
					//6.创建一个ModelAndViewContainer,并填充它
                    ModelAndViewContainer mavContainer = new ModelAndViewContainer();
                    mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
                    //7.调用并处理
                    invocableMethod.invokeAndHandle(webRequest, mavContainer);
						//1.调用请求
						InvocableHandlerMethod#invokeForRequest(NativeWebRequest request, @Nullable ModelAndViewContainer mavContainer, Object... providedArgs)
							//获取方法参数值数组
							Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
								//获取MethodParameter数组
								MethodParameter[] parameters = getMethodParameters();
								//遍历每个MethodParameter
								for(int i = 0; i < parameters.length; i++){
									args[i] = findProvidedArgument(parameter, providedArgs);
									if (args[i] != null) {
										continue;
									}
									if (!this.resolvers.supportsParameter(parameter)) {
										throw new IllegalStateException(formatArgumentError(parameter, "No suitable resolver"));
									}
									try {
										args[i] = this.resolvers.resolveArgument(parameter, mavContainer, request, this.dataBinderFactory);
									}
								}
								return args;
							//执行调用,返回执行目标方法得到的返回值
							return doInvoke(args);
						//2.根据@ResponseStatus注解设置响应状态
						setResponseStatus(webRequest)
						//3.遍历已注册的HandlerMethodReturnValueHandler并调用支持它的那个,注:this.returnValueHandlers --> HandlerMethodReturnValueHandlerComposite
						this.returnValueHandlers.handleReturnValue(returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
							//根据返回值和返回类型,找到合适的HandlerMethodReturnValueHandler,eg.RequestResponseBodyMethodProcessor、ViewNameMethodReturnValueHandler
							HandlerMethodReturnValueHandler handler = selectHandler(returnValue, returnType);
								for (HandlerMethodReturnValueHandler handler : this.returnValueHandlers) {
									if (isAsyncValue && !(handler instanceof AsyncHandlerMethodReturnValueHandler)) {
										continue;
									}
									if (handler.supportsReturnType(returnType)) {
										return handler;
									}
								}
								return null;
							if (handler == null) {
								throw new IllegalArgumentException("Unknown return value type: " + returnType.getParameterType().getName());
							}
							//处理返回值,即调用找到的HandlerMethodReturnValueHandler的handleReturnValue()方法
							handler.handleReturnValue(returnValue, returnType, mavContainer, webRequest);
								//这里是RequestResponseBodyMethodProcessor#handleReturnValue()的代码
								mavContainer.setRequestHandled(true);
								//返回值写入Web请求,可能会涉及到 ResponseBodyAdvice
								writeWithMessageConverters(returnValue, returnType, webRequest);
                    //8.构建ModelAndView并返回
                    return getModelAndView(mavContainer, modelFactory, webRequest);
				//根据此生成器的设置准备给定的响应
				WebContentGenerator#prepareResponse(HttpServletResponse response)
				//方法执行完成,返回ModelAndView
				return mav;
        //6.应用已注册拦截器的postHandle方法
        HandlerExecutionChain#applyPostHandle(HttpServletRequest request, HttpServletResponse response, ModelAndView mv)
            //返回要应用的拦截器数组(按给定顺序)
            HandlerExecutionChain#getInterceptors()
            //遍历得到的拦截器数组,拦截执行程序的执行
            for (int i = getInterceptors().length - 1; i >= 0; i--) {
                HandlerInterceptor interceptor = getInterceptors()[i];
                //拦截执行程序,在HandlerAdapter实际调用处理程序之后但在DispatcherServlet呈现视图之前调用。
                interceptor.postHandle(request, response, this.handler, mv);
            }
        //7.处理handler selection和handler invocation的结果(决定页面该如何响应),可以是ModelAndView或要解析为ModelAndView的Exception
        DispatcherServlet#processDispatchResult(HttpServletRequest request, HttpServletResponse response,HandlerExecutionChain mappedHandler, ModelAndView mv, Exception exception)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值