SpringMVC源码阅读

调用org.springframework.web.servlet.FrameworkServlet中的service方法,该类是org.springframework.web.servlet.DispatcherServlet(也就是前端控制器)的父
/**
	 * Override the parent class implementation in order to intercept PATCH requests.
	 */
	@Override
	protected void service(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());
		if (HttpMethod.PATCH == httpMethod || httpMethod == null) {
			processRequest(request, response);
		}
		else {
			super.service(request, response);
		}
	}
如果请求为PATCH请求,则调用本类的processRequest(request, response)方法,这里发的请求是GET请求,则调用该类父类( javax.servlet.http.HttpServlet)的service方法,由于javax.servlet.http.HttpServlet的源码无法查看,就直接跳过,接着执行org.springframework.web.servlet.FrameworkServlet的doGet方法
/**
	 * Delegate GET requests to processRequest/doService.
	 * <p>Will also be invoked by HttpServlet's default implementation of {@code doHead},
	 * with a {@code NoBodyResponse} that just captures the content length.
	 *将GET请求委托给processRequest/doService。
     * <p>也会被HttpServlet的默认实现{@code doHead}调用,
     *使用{@code NoBodyResponse}来捕获内容长度
	 * @see #doService
	 * @see #doHead
	 */
	@Override
	protected final void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		processRequest(request, response);
	}
调用org.springframework.web.servlet.FrameworkServlet的processRequest方法:
/**
	 * Process this request, publishing an event regardless of the outcome.
	 * <p>The actual event handling is performed by the abstract
	 * {@link #doService} template method.\
	 *处理此请求,无论结果如何都要发布事件。实际的事件处理是由抽象执行的
     * {@link #doService}模板方法。
	 */
	protected final void processRequest(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

	//省略。。。

		try {
			doService(request, response);
		}
	//省略。。。
	}
调用org.springframework.web.servlet.DispatcherServlet的doService方法:
/**
	 * Exposes the DispatcherServlet-specific request attributes and delegates to {@link #doDispatch}
	 * for the actual dispatching.
	 *公开dispatcherservlet特定的请求属性和委托给{@link #doDispatch}
     *实际调度
	 */
	@Override
	protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
    //省略。。
		try {
			doDispatch(request, response);
		}
    //省略。。。
	}
调用org.springframework.web.servlet.DispatcherServlet的doDispatch方法,将处理请求的操作发送给指定的Handle:
/**
	 * 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.
    * 处理发送到处理程序的实际调度。
    * <p>处理程序将通过应用servlet的HandlerMappings顺序获得。
    * HandlerAdapter将通过查询servlet安装的HandlerAdapter获得
    *找到第一个支持处理程序类的。
    *所有HTTP方法都是由这个方法处理的。这取决于handleradapter或处理程序
    *自行决定哪些方法是可接受的。
	 * @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 {
				processedRequest = checkMultipart(request);
				multipartRequestParsed = (processedRequest != request);

				// Determine handler for the current request.
				mappedHandler = getHandler(processedRequest);
				if (mappedHandler == null || mappedHandler.getHandler() == null) {
					noHandlerFound(processedRequest, response);
					return;
				}

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

				// Process last-modified header, if supported by the handler.
				String method = request.getMethod();
				boolean isGet = "GET".equals(method);
				if (isGet || "HEAD".equals(method)) {
					long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
					if (logger.isDebugEnabled()) {
						logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
					}
					if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
						return;
					}
				}

				if (!mappedHandler.applyPreHandle(processedRequest, response)) {
					return;
				}

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

				if (asyncManager.isConcurrentHandlingStarted()) {
					return;
				}

				applyDefaultViewName(processedRequest, mv);
				mappedHandler.applyPostHandle(processedRequest, response, mv);
			}
			}
调用 org.springframework.web.servlet.DispatcherServlet的getHandler方法,获得当前请求的HandlerExecutionChain:
/**
	 * Return the HandlerExecutionChain for this request.
	 * <p>Tries all handler mappings in order.
	 * @param request current HTTP request
	 * @return the HandlerExecutionChain, or {@code null} if no handler could be found
	 */
	protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		for (HandlerMapping hm : this.handlerMappings) {
			if (logger.isTraceEnabled()) {
				logger.trace(
						"Testing handler map [" + hm + "] in DispatcherServlet with name '" + getServletName() + "'");
			}
			HandlerExecutionChain handler = hm.getHandler(request);
			if (handler != null) {
				return handler;
			}
		}
		return null;
handlerMappings中的内容:
[org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping@14a3b3ff,
org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping@109c25b3,
org.springframework.web.servlet.handler.SimpleUrlHandlerMapping@559eb9c4]
调用org.springframework.web.servlet.handler.AbstractHandlerMapping的getHander方法,为当前请求查找handler:
/**
	 * Look up a handler for the given request, falling back to the default
	 * handler if no specific one is found.
	 * @param request current HTTP request
	 * @return the corresponding handler instance, or the default handler
	 * @see #getHandlerInternal
	 */
	@Override
	public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		Object handler = getHandlerInternal(request);
		if (handler == null) {
			handler = getDefaultHandler();
		}
		if (handler == null) {
			return null;
		}
		// Bean name or resolved handler?
		if (handler instanceof String) {
			String handlerName = (String) handler;
			handler = getApplicationContext().getBean(handlerName);
		}

		HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);
		if (CorsUtils.isCorsRequest(request)) {
			CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request);
			CorsConfiguration handlerConfig = getCorsConfiguration(handler, request);
			CorsConfiguration config = (globalConfig != null ? globalConfig.combine(handlerConfig) : handlerConfig);
			executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
		}
		return executionChain;
	}
调用org.springframework.web.servlet.handler.AbstractHandlerMethodMapping的getHandlerInternal方法:
/**
	 * Look up a handler method for the given request.
	 */
	@Override
	protected HandlerMethod getHandlerInternal(HttpServletRequest request) throws Exception {
		String lookupPath = getUrlPathHelper().getLookupPathForRequest(request);
		if (logger.isDebugEnabled()) {
			logger.debug("Looking up handler method for path " + lookupPath);
		}
		this.mappingRegistry.acquireReadLock();
		try {
			HandlerMethod handlerMethod = lookupHandlerMethod(lookupPath, request);
			if (logger.isDebugEnabled()) {
				if (handlerMethod != null) {
					logger.debug("Returning handler method [" + handlerMethod + "]");
				}
				else {
					logger.debug("Did not find handler method for [" + lookupPath + "]");
				}
			}
			return (handlerMethod != null ? handlerMethod.createWithResolvedBean() : null);
		}
		finally {
			this.mappingRegistry.releaseReadLock();
		}
	}
调用org.springframework.web.servlet.handler.AbstractHandlerMethodMapping的lookupHandlerMethod方法,寻找当前请求的最佳匹配,如果存在多个匹配,则选择最佳匹配:
/**
	 * Look up the best-matching handler method for the current request.
	 * If multiple matches are found, the best match is selected.
	 * @param lookupPath mapping lookup path within the current servlet mapping
	 * @param request the current request
	 * @return the best-matching handler method, or {@code null} if no match
	 * @see #handleMatch(Object, String, HttpServletRequest)
	 * @see #handleNoMatch(Set, String, HttpServletRequest)
	 */
	protected HandlerMethod lookupHandlerMethod(String lookupPath, HttpServletRequest request) throws Exception {
		List<Match> matches = new ArrayList<Match>();
		List<T> directPathMatches = this.mappingRegistry.getMappingsByUrl(lookupPath);
		if (directPathMatches != null) {
			addMatchingMappings(directPathMatches, matches, request);
		}
		if (matches.isEmpty()) {
			// No choice but to go through all mappings...
			addMatchingMappings(this.mappingRegistry.getMappings().keySet(), matches, request);
		}

		if (!matches.isEmpty()) {
			Comparator<Match> comparator = new MatchComparator(getMappingComparator(request));
			Collections.sort(matches, comparator);
			if (logger.isTraceEnabled()) {
				logger.trace("Found " + matches.size() + " matching mapping(s) for [" +
						lookupPath + "] : " + matches);
			}
			Match bestMatch = matches.get(0);
			if (matches.size() > 1) {
				if (CorsUtils.isPreFlightRequest(request)) {
					return PREFLIGHT_AMBIGUOUS_MATCH;
				}
				Match secondBestMatch = matches.get(1);
				if (comparator.compare(bestMatch, secondBestMatch) == 0) {
					Method m1 = bestMatch.handlerMethod.getMethod();
					Method m2 = secondBestMatch.handlerMethod.getMethod();
					throw new IllegalStateException("Ambiguous handler methods mapped for HTTP path '" +
							request.getRequestURL() + "': {" + m1 + ", " + m2 + "}");
				}
			}
			handleMatch(bestMatch.mapping, lookupPath, request);
			return bestMatch.handlerMethod;
		}
		else {
			return handleNoMatch(this.mappingRegistry.getMappings().keySet(), lookupPath, request);
		}
	}
注册拦截器:
handler内容:
HandlerExecutionChain with handler [public com.tarena.vo.Result com.tarena.controller.UserControllerAsync.login1(com.tarena.entiry.User)] and 1 interceptor
protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
		HandlerExecutionChain chain = (handler instanceof HandlerExecutionChain ?
				(HandlerExecutionChain) handler : new HandlerExecutionChain(handler));

		String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
		for (HandlerInterceptor interceptor : this.adaptedInterceptors) {
			if (interceptor instanceof MappedInterceptor) {
				MappedInterceptor mappedInterceptor = (MappedInterceptor) interceptor;
				if (mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
					chain.addInterceptor(mappedInterceptor.getInterceptor());
				}
			}
			else {
				chain.addInterceptor(interceptor);
			}
		}
		return chain;
	}
接着回到 org.springframework.web.servlet.DispatcherServlet的doDispatch方法中:
                // Determine handler adapter for the current request.
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
调用 org.springframework.web.servlet.DispatcherServlet的getHandlerAdapter方法,返回当前对象的处理器适配器:
/**
	 * Return the HandlerAdapter for this handler object.
	 * @param handler the handler object to find an adapter for
	 * @throws ServletException if no HandlerAdapter can be found for the handler. This is a fatal error.
	 */
	protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
		for (HandlerAdapter ha : this.handlerAdapters) {
			if (logger.isTraceEnabled()) {
				logger.trace("Testing handler adapter [" + ha + "]");
			}
			if (ha.supports(handler)) {
				return ha;
			}
		}
		throw new ServletException("No adapter for handler [" + handler +
				"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
	}
HandlerAdapter:
[org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter@6ec29621,
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter@4c0b551a,
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter@54188c7]
doDispatch方法:
            // Actually invoke the handler.调用实际的处理程序
			mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
调用org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter的handleInternal方法:
@Override
	protected ModelAndView handleInternal(HttpServletRequest request,
			HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

		ModelAndView mav;
		checkRequest(request);

		// Execute invokeHandlerMethod in synchronized block if required.如果需要,在synchronized块中执行invokeHandlerMethod。
		if (this.synchronizeOnSession) {
			HttpSession session = request.getSession(false);
			if (session != null) {
				Object mutex = WebUtils.getSessionMutex(session);
				synchronized (mutex) {
					mav = invokeHandlerMethod(request, response, handlerMethod);
				}
			}
			else {
				// No HttpSession available -> no mutex necessary没有可用的HttpSession ->不需要互斥
				mav = invokeHandlerMethod(request, response, handlerMethod);
			}
		}
		else {
			// No synchronization on session demanded at all...会话上根本不需要同步…
			mav = invokeHandlerMethod(request, response, handlerMethod);
		}

		if (!response.containsHeader(HEADER_CACHE_CONTROL)) {
			if (getSessionAttributesHandler(handlerMethod).hasSessionAttributes()) {
				applyCacheSeconds(response, this.cacheSecondsForSessionAttributeHandlers);
			}
			else {
				prepareResponse(response);
			}
		}

		return mav;
	}
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter方法,invokeHandlerMethod:
/**
	 * Invoke the {@link RequestMapping} handler method preparing a {@link ModelAndView}
	 * if view resolution is required.
	 * 调用{@link RequestMapping}处理程序方法准备一个{@link ModelAndView}
    *如果需要视图分辨率。
	 * @since 4.2
	 * @see #createInvocableHandlerMethod(HandlerMethod)
	 */
	protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
			HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

		ServletWebRequest webRequest = new ServletWebRequest(request, response);
		try {
			WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
			ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
            //创建一个可调用的方法
			ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
			//省略。。。为invocableMethod设置一些属性

			ModelAndViewContainer mavContainer = new ModelAndViewContainer();
			mavContainer.addAllAttributes(RequestContextUtils.getInputFlashMap(request));
			modelFactory.initModel(webRequest, mavContainer, invocableMethod);
			mavContainer.setIgnoreDefaultModelOnRedirect(this.ignoreDefaultModelOnRedirect);
            //创建一个异步的请求实例
			AsyncWebRequest asyncWebRequest = WebAsyncUtils.createAsyncWebRequest(request, response);
			asyncWebRequest.setTimeout(this.asyncRequestTimeout);
            //获取当前请求的WebAsyncManager,如果没有找到,则创建并将其与请求关联。
			WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
		    //省略...为asyncManager设置一些属性

			if (asyncManager.hasConcurrentResult()) {
				Object result = asyncManager.getConcurrentResult();
				mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
				asyncManager.clearConcurrentResult();
				if (logger.isDebugEnabled()) {
					logger.debug("Found concurrent result value [" + result + "]");
				}
				invocableMethod = invocableMethod.wrapConcurrentResult(result);
			}

			invocableMethod.invokeAndHandle(webRequest, mavContainer);
			if (asyncManager.isConcurrentHandlingStarted()) {
				return null;
			}

			return getModelAndView(mavContainer, modelFactory, webRequest);
		}
		finally {
			webRequest.requestCompleted();
		}
	}
org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod的invokeAndHandle方法:
/**
	 * Invoke the method and handle the return value through one of the
	 * configured {@link HandlerMethodReturnValueHandler}s.调用该方法并通过
        *配置{@link HandlerMethodReturnValueHandler}s
	 * @param webRequest the current request
	 * @param mavContainer the ModelAndViewContainer for this request
	 * @param providedArgs "given" arguments matched by type (not resolved)
	 */
	public void invokeAndHandle(ServletWebRequest webRequest, ModelAndViewContainer mavContainer,
			Object... providedArgs) throws Exception {

		Object returnValue = invokeForRequest(webRequest, mavContainer, providedArgs);
		setResponseStatus(webRequest);

		if (returnValue == null) {
			if (isRequestNotModified(webRequest) || hasResponseStatus() || mavContainer.isRequestHandled()) {
				mavContainer.setRequestHandled(true);
				return;
			}
		}
		else if (StringUtils.hasText(this.responseReason)) {
			mavContainer.setRequestHandled(true);
			return;
		}

		mavContainer.setRequestHandled(false);
		try {
			this.returnValueHandlers.handleReturnValue(
					returnValue, getReturnValueType(returnValue), mavContainer, webRequest);
		}
		catch (Exception ex) {
			if (logger.isTraceEnabled()) {
				logger.trace(getReturnValueHandlingErrorMessage("Error handling return value", returnValue), ex);
			}
			throw ex;
		}
	}
org.springframework.web.method.support.InvocableHandlerMethod的invokeForRequest方法:
/**
	 * Invoke the method after resolving its argument values in the context of the given request.
	 * <p>Argument values are commonly resolved through {@link HandlerMethodArgumentResolver}s.
	 * The {@code providedArgs} parameter however may supply argument values to be used directly,
	 * i.e. without argument resolution. Examples of provided argument values include a
	 * {@link WebDataBinder}, a {@link SessionStatus}, or a thrown exception instance.
	 * Provided argument values are checked before argument resolvers.
	 * @param request the current request
	 * @param mavContainer the ModelAndViewContainer for this request
	 * @param providedArgs "given" arguments matched by type, not resolved
	 * @return the raw value returned by the invoked method
	 * @exception Exception raised if no suitable argument resolver can be found,
	 * or if the method raised an exception
	 */
	public Object invokeForRequest(NativeWebRequest request, ModelAndViewContainer mavContainer,
			Object... providedArgs) throws Exception {

		Object[] args = getMethodArgumentValues(request, mavContainer, providedArgs);
		if (logger.isTraceEnabled()) {
			logger.trace("Invoking '" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
					"' with arguments " + Arrays.toString(args));
		}
		Object returnValue = doInvoke(args);
		if (logger.isTraceEnabled()) {
			logger.trace("Method [" + ClassUtils.getQualifiedMethodName(getMethod(), getBeanType()) +
					"] returned [" + returnValue + "]");
		}
		return returnValue;
	}
org.springframework.web.method.support.InvocableHandlerMethod的doInvoke方法:
/**
	 * Invoke the handler method with the given argument values.
	 调配带参数的handler方法
	 */
	protected Object doInvoke(Object... args) throws Exception {
		ReflectionUtils.makeAccessible(getBridgedMethod());
		try {
			return getBridgedMethod().invoke(getBean(), args);
		}
		catch (IllegalArgumentException ex) {
			assertTargetBean(getBridgedMethod(), getBean(), args);
			String text = (ex.getMessage() != null ? ex.getMessage() : "Illegal argument");
			throw new IllegalStateException(getInvocationErrorMessage(text, args), ex);
		}
		catch (InvocationTargetException ex) {
			// Unwrap for HandlerExceptionResolvers ...
			Throwable targetException = ex.getTargetException();
			if (targetException instanceof RuntimeException) {
				throw (RuntimeException) targetException;
			}
			else if (targetException instanceof Error) {
				throw (Error) targetException;
			}
			else if (targetException instanceof Exception) {
				throw (Exception) targetException;
			}
			else {
				String text = getInvocationErrorMessage("Failed to invoke handler method", args);
				throw new IllegalStateException(text, targetException);
			}
		}
	}
java.lang.reflect.Method的invoke方法(反射调用controller中对应的方法):
@CallerSensitive
    public Object invoke(Object obj, Object... args)
        throws IllegalAccessException, IllegalArgumentException,
           InvocationTargetException
    {
        if (!override) {
            if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) {
                Class<?> caller = Reflection.getCallerClass();
                checkAccess(caller, clazz, obj, modifiers);
            }
        }
        MethodAccessor ma = methodAccessor;             // read volatile
        if (ma == null) {
            ma = acquireMethodAccessor();
        }
        return ma.invoke(obj, args);
    }
Controller层方法:
@Controller
@RequestMapping(value="userAsync/")
public class UserControllerAsync {
	
	@RequestMapping(value="login.do",method=RequestMethod.GET)
	@ResponseBody //把对象转换成json字符串并相应给js,借助jackson
	public Result login1(User user){
		Result result = new Result();
		System.out.println(user.getUsername()+"--"+user.getPassword());
		//调用业务
		result.setStatus(1);
		result.setMessge("登陆成功");
		result.setData(user);
		return result;
	}
}
方法执行完毕之后,拿到返回值,这里返回的数据是JSON类型的,所以会调用方法,返回值序列化为JSON字符串
/**
     * Method called to access property that this bean stands for, from within
     * given bean, and to serialize it as a JSON Object field using appropriate
     * serializer.
     */
    @Override
    public void serializeAsField(Object bean, JsonGenerator gen,
            SerializerProvider prov) throws Exception {
        // inlined 'get()'
        final Object value = (_accessorMethod == null) ? _field.get(bean)
                : _accessorMethod.invoke(bean, (Object[]) null);

        // Null handling is bit different, check that first
        if (value == null) {
            if (_nullSerializer != null) {
                gen.writeFieldName(_name);
                _nullSerializer.serialize(null, gen, prov);
            }
            return;
        }
        // then find serializer to use
        JsonSerializer<Object> ser = _serializer;
        if (ser == null) {
            Class<?> cls = value.getClass();
            PropertySerializerMap m = _dynamicSerializers;
            ser = m.serializerFor(cls);
            if (ser == null) {
                ser = _findAndAddDynamic(m, cls, prov);
            }
        }
        // and then see if we must suppress certain values (default, empty)
        if (_suppressableValue != null) {
            if (MARKER_FOR_EMPTY == _suppressableValue) {
                if (ser.isEmpty(prov, value)) {
                    return;
                }
            } else if (_suppressableValue.equals(value)) {
                return;
            }
        }
        // For non-nulls: simple check for direct cycles
        if (value == bean) {
            // three choices: exception; handled by call; or pass-through
            if (_handleSelfReference(bean, gen, prov, ser)) {
                return;
            }
        }
        gen.writeFieldName(_name);
        if (_typeSerializer == null) {
            ser.serialize(value, gen, prov);
        } else {
            ser.serializeWithType(value, gen, prov, _typeSerializer);
        }
    }
org.springframework.web.servlet.DispatcherServlet.doDispatch
//是否需要视图名称转换
applyDefaultViewName(processedRequest, mv);
//调用拦截器的PostHandle方法
mappedHandler.applyPostHandle(processedRequest, response, mv);
//处理处理程序选择和处理程序调用的结果,它将模型和视图或异常解析为模型和视图
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

#### 总结:

Spring MVC 执行过程:
调用service方法,更具请求方法式的不同调用不同的方法,将get请求委托给processRequest/doService,处理请求,将请求委托给doDispatch,根据当前请求查找处理程序(Handler),如果有多个请求被匹配,则选择最佳匹配项,如果没有匹配的,则返回默认的handler(DefaultServletHttpRequestHandler),向handler注册拦截器:
最后handler的内容:
HandlerExecutionChain with handler [public com.tarena.vo.Result com.tarena.controller.UserControllerAsync.login1(com.tarena.entiry.User)] and 1 interceptor
通过handler获取handler adapter
org.springframework.web.servlet.DispatcherServlet.doDispatch调用preHandle:
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
					return;
				}
handler adapter内容:
org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter@54188c7
调用实际的处理程序,反射调用Controller中的方法,获得返回结果,根据场景对返回的对象进行处理,
如果为存在ViewName则调用视图模板解析器渲染数据,如果需要json数据,则将对象序列化为JSON字符串
springmvc5中有四个非抽象的HandlerAdapter:
1.SimpleServletHandlerAdapter
2.SimpleControllerHandlerAdapter
3.HttpRequestHandlerAdapter
4.RequestMappingHandlerAdapter

springmvc通过HandlerMapping将请求URL映射到handler,再将handler交给HandlerAdapter进行调用处理。
HandlerAdapter里重要的有两个方法:
supports()方法用来判断当前HandlerAdapter是否可以调用处理handler;
handle()方法用来调用handler,具体的来处理请求。
接下来对四个HandlerAdapter进行一一分析。
1.SimpleServletHandlerAdapter
SimpleServletHandlerAdapter可以处理类型为Servlet的handler,对handler的处理是调用Servlet的service方法处理请求。
看具体的配置和handler:
可以使用BeanNameUrlHandlerMapping将请求URL"/testServlet"和handler(Servlet1)相映射,使用SimpleServletHandlerAdapter调用处理成功:
2.SimpleControllerHandlerAdapter
SimpleControllerHandlerAdapter可以处理类型为Controller的handler,对handler的处理是调用Controller的handleRequest()方法。
Controller是springmvc的一个接口:
看具体的配置和handler:
可以使用BeanNameUrlHandlerMapping将请求URL"/testController"和handler(Controller1)相映射,使用SimpleControllerHandlerAdapter调用处理成功:
3.HttpRequestHandlerAdapter
HttpRequestHandlerAdapter可以处理类型为HttpRequestHandler的handler,对handler的处理是调用HttpRequestHandler的handleRequest()方法。
HttpRequestHandler是springmvc的一个接口:
看具体的配置和handler:
可以使用BeanNameUrlHandlerMapping将请求URL"/testHttpRequestHandler"和handler(HttpRequestHandler1)相映射,使用HttpRequestHandlerAdapter调用处理成功:
4.RequestMappingHandlerAdapter
RequestMappingHandlerAdapter类代码相比之前三个HandlerAdapter,代码要复杂的多,这里只截取重要的部分:
RequestMappingHandlerAdapter可以处理类型为HandlerMethod的handler,对handler的处理是调用通过java反射调用HandlerMethod的方法。
看具体的配置和handler:
只有RequestMappingHandlerAdapter有order属性,其他三个HandlerAdapter没有order属性。前三个HandlerAdapter处理的handler类型各不相同,处理也比较简单,不需要使用order区分优先级。
使用RequestMappingHandlerMapping将请求URL"/test11"和handler(TestController.test2())相映射(需在方法上添加@RequestMapping注解),使用RequestMappingHandlerAdapter调用处理成功:

到这里,springmvc的四个HandlerAdapter就分析完了。前三个HandlerAdapter对handler的处理比较简单,HttpRequestHandlerAdapter和SimpleControllerHandlerAdapter直接调用固定唯一的方法handleRequest();
SimpleServletHandlerAdapter直接调用固定唯一的方法service()。
RequestMappingHandlerAdapter实现起来就很复杂了,处理调用的方法不唯一也不固定,需要有更多的处理。

在HandlerAdapter处理的返回值上,虽然统一的返回ModelAndView对象,但HttpRequestHandlerAdapter和SimpleServletHandlerAdapter实际上都是直接returnnull;
SimpleControllerHandlerAdapter返回handler(Controller)处理的结果,ModelAndView对象或者null;
RequestMappingHandlerAdapter是通过反射调用获取的结果,这个结果可能是ModelAndView对象,也可能是String类型对象,还可以是一个map等,需要对返回的结果做更多的判断处理,再返回统一的ModelAndView对象

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值