¿Cómo resuelve springMVC vistas?

¿Cómo distribuye SpringMVC las vistas analizadas de las solicitudes?

Primero entienda los 9 componentes principales de SpringMVC

// 文件解析
/** MultipartResolver used by this servlet. */
@Nullable
private MultipartResolver multipartResolver;
// 国际化解析
/** LocaleResolver used by this servlet. */
@Nullable
private LocaleResolver localeResolver;
// 主题解析器
/** ThemeResolver used by this servlet. */
@Nullable
private ThemeResolver themeResolver;
// 映射表
/** List of HandlerMappings used by this servlet. */
@Nullable
private List<HandlerMapping> handlerMappings;
// 适配器表
/** List of HandlerAdapters used by this servlet. */
@Nullable
private List<HandlerAdapter> handlerAdapters;
// 异常处理
/** List of HandlerExceptionResolvers used by this servlet. */
@Nullable
private List<HandlerExceptionResolver> handlerExceptionResolvers;
//请求转视图名
/** RequestToViewNameTranslator used by this servlet. */
@Nullable
private RequestToViewNameTranslator viewNameTranslator;
// 重定向数据
/** FlashMapManager used by this servlet. */
@Nullable
private FlashMapManager flashMapManager;
// 视图解析器
/** List of ViewResolvers used by this servlet. */
@Nullable
private List<ViewResolver> viewResolvers;

1. Reciba la solicitud htttp

2. La solicitud de filtrado contiene una serie de filtros que generalmente son métodos de dofiltro

3. Utilice DispatchSerlet.class para procesar la solicitud (clase principal)

4. Use handleMappings para encontrar el controlador y el método de destino que deben procesarse de acuerdo con la solicitud

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

¿Cómo encontrarlo?

@Nullable
	protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
		if (this.handlerMappings != null) {
			for (HandlerMapping mapping : this.handlerMappings) {
				HandlerExecutionChain handler = mapping.getHandler(request);
				if (handler != null) {
					return handler;
				}
			}
		}
		return null;
	}

Es sencillo recorrer todos los HandlerMapping

En el proceso de inicialización de HandlerMapping, hay al menos un handlerMapping

// handlerMappings的初始化
private void initHandlerMappings(ApplicationContext context) {
		this.handlerMappings = null;
		if (this.detectAllHandlerMappings) {
			// Find all HandlerMappings in the ApplicationContext, including ancestor contexts.
			Map<String, HandlerMapping> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.handlerMappings = new ArrayList<>(matchingBeans.values());
				// We keep HandlerMappings in sorted order.
				AnnotationAwareOrderComparator.sort(this.handlerMappings);
			}
		}
		else {
			try {
				HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
				this.handlerMappings = Collections.singletonList(hm);
			}
			catch (NoSuchBeanDefinitionException ex) {
				// Ignore, we'll add a default HandlerMapping later.
			}
		}

		// Ensure we have at least one HandlerMapping, by registering
		// a default HandlerMapping if no other mappings are found.
		if (this.handlerMappings == null) {
			this.handlerMappings = getDefaultStrategies(context, HandlerMapping.class);
			if (logger.isTraceEnabled()) {
				logger.trace("No HandlerMappings declared for servlet '" + getServletName() +
						"': using default strategies from DispatcherServlet.properties");
			}
		}
	}

5. Seleccione el manejador apropiado Adaptador de acuerdo con el manejador

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

6. Ejecute el método de destino y genere ModelAndView

Adaptador

mv = ha.handle(processedRequest, response, mappedHandler.getHandler());   

Prueba de POJO, el tipo de cadena en realidad solo tiene un valor de retorno, por lo que en este momento, mav = nulo;

7. Devolver resultados según ModelAndView

Ver vista de renderizado, omitir la vista de carga si no

processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

El diagrama de flujo es el siguiente

Inserte la descripción de la imagen aquí

Método principal de DispatcherServlet dodispatch:

	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);
				// 找到处理这个请求的Controller
				// Determine handler for the current request.
				mappedHandler = getHandler(processedRequest);
                		// 没有找到处理的Controller准备返回
				if (mappedHandler == 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 (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
						return;
					}
				}

				if (!mappedHandler.applyPreHandle(processedRequest, response)) {
					return;
				}
				// 生成ModelAndView (最最最核心的部分)
				// Actually invoke the handler.
				mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

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

				applyDefaultViewName(processedRequest, mv);
				mappedHandler.applyPostHandle(processedRequest, response, mv);
			}
			catch (Exception ex) {
				dispatchException = ex;
			}
			catch (Throwable err) {
				// As of 4.3, we're processing Errors thrown from handler methods as well,
				// making them available for @ExceptionHandler methods and other scenarios.
				dispatchException = new NestedServletException("Handler dispatch failed", err);
			}
            	// 渲染ModelAndView 到页面
			processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
		}
		catch (Exception ex) {
			triggerAfterCompletion(processedRequest, response, mappedHandler, ex);
		}
		catch (Throwable err) {
			triggerAfterCompletion(processedRequest, response, mappedHandler,
					new NestedServletException("Handler processing failed", err));
		}
		finally {
			if (asyncManager.isConcurrentHandlingStarted()) {
				// Instead of postHandle and afterCompletion
				if (mappedHandler != null) {
					mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
				}
			}
			else {
				// Clean up any resources used by a multipart request.
				if (multipartRequestParsed) {
					cleanupMultipart(processedRequest);
				}
			}
		}
	}

El resultado

Obviamente SpringMVC utilizaModo adaptador

Elija diferentes clases de acuerdo a diferentes métodos.

22 artículos originales publicados · Me gusta2 · Visitas 881

Supongo que te gusta

Origin blog.csdn.net/weixin_41685373/article/details/104973688
Recomendado
Clasificación