SpringBoot的SpringMVC视图解析器源码学习笔记

SpringMVC视图解析器

	//根据视图名得到视图对象
	public class ThymeleafViewResolver extends AbstractCachingViewResolver implements Ordered {
		//创建视图对象
		@Override
		protected View createView(final String viewName, final Locale locale) throws Exception {
			// First possible call to check "viewNames": before processing redirects and forwards
        if (!this.alwaysProcessRedirectAndForward && !canHandle(viewName, locale)) {
            vrlogger.trace("[THYMELEAF] View \"{}\" cannot be handled by ThymeleafViewResolver. Passing on to the next resolver in the chain.", viewName);
            return null;
        }
        // Process redirects (HTTP redirects)
		//如果以redirect:开始
        if (viewName.startsWith(REDIRECT_URL_PREFIX)) {
            vrlogger.trace("[THYMELEAF] View \"{}\" is a redirect, and will not be handled directly by ThymeleafViewResolver.", viewName);
            final String redirectUrl = viewName.substring(REDIRECT_URL_PREFIX.length(), viewName.length());
            //为我们创建重定向视图
			final RedirectView view = new RedirectView(redirectUrl, isRedirectContextRelative(), isRedirectHttp10Compatible());
            return (View) getApplicationContext().getAutowireCapableBeanFactory().initializeBean(view, viewName);
        }
        // Process forwards (to JSP resources)
		//如果以forward:开始
        if (viewName.startsWith(FORWARD_URL_PREFIX)) {
            // The "forward:" prefix will actually create a Servlet/JSP view, and that's precisely its aim per the Spring
            // documentation. See http://docs.spring.io/spring-framework/docs/4.2.4.RELEASE/spring-framework-reference/html/mvc.html#mvc-redirecting-forward-prefix
            vrlogger.trace("[THYMELEAF] View \"{}\" is a forward, and will not be handled directly by ThymeleafViewResolver.", viewName);
            final String forwardUrl = viewName.substring(FORWARD_URL_PREFIX.length(), viewName.length());
            //为我们创建InternalResourceView
			return new InternalResourceView(forwardUrl);
        }
        // Second possible call to check "viewNames": after processing redirects and forwards
        if (this.alwaysProcessRedirectAndForward && !canHandle(viewName, locale)) {
            vrlogger.trace("[THYMELEAF] View \"{}\" cannot be handled by ThymeleafViewResolver. Passing on to the next resolver in the chain.", viewName);
            return null;
        }
        vrlogger.trace("[THYMELEAF] View {} will be handled by ThymeleafViewResolver and a " +
                        "{} instance will be created for it", viewName, getViewClass().getSimpleName());
        return loadView(viewName, locale);
		}
	}
	public static final String FORWARD_URL_PREFIX = "forward:";
	public static final String REDIRECT_URL_PREFIX = "redirect:";

RedirectView//为我们创建重定向视图

		源码:
		public class RedirectView extends AbstractUrlBasedView implements SmartView {
			//渲染
			@Override
			protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request,
					HttpServletResponse response) throws IOException {

				String targetUrl = createTargetUrl(model, request);
				targetUrl = updateTargetUrl(targetUrl, model, request, response);

				// Save flash attributes
				RequestContextUtils.saveOutputFlashMap(targetUrl, request, response);

				// Redirect
				sendRedirect(request, response, targetUrl, this.http10Compatible);
			}
			protected void sendRedirect(HttpServletRequest request, HttpServletResponse response,
					String targetUrl, boolean http10Compatible) throws IOException {

				String encodedURL = (isRemoteHost(targetUrl) ? targetUrl : response.encodeRedirectURL(targetUrl));
				if (http10Compatible) {
					HttpStatus attributeStatusCode = (HttpStatus) request.getAttribute(View.RESPONSE_STATUS_ATTRIBUTE);
					if (this.statusCode != null) {
						response.setStatus(this.statusCode.value());
						response.setHeader("Location", encodedURL);
					}
					else if (attributeStatusCode != null) {
						response.setStatus(attributeStatusCode.value());
						response.setHeader("Location", encodedURL);
					}
					else {
						// Send status code 302 by default.
						//原生servlet的重定向
						response.sendRedirect(encodedURL);
					}
				}
				else {
					HttpStatus statusCode = getHttp11StatusCode(request, response, targetUrl);
					response.setStatus(statusCode.value());
					response.setHeader("Location", encodedURL);
				}
			}
		}

InternalResourceView//为我们创建InternalResourceView

		源码:
		public class InternalResourceView extends AbstractUrlBasedView {
			@Override
			protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
				// Determine the path for the request dispatcher.
				//拿到路径
				String dispatcherPath = prepareForRendering(request, response);
				
				// Obtain a RequestDispatcher for the target resource (typically a JSP).
				//拿到转发器
				RequestDispatcher rd = getRequestDispatcher(request, dispatcherPath);
				if (rd == null) {
					throw new ServletException("Could not get RequestDispatcher for [" + getUrl() +
							"]: Check that the corresponding file exists within your web application archive!");
				}

				// If already included or response already committed, perform include, else forward.
				if (useInclude(request, response)) {
					response.setContentType(getContentType());
					if (logger.isDebugEnabled()) {
						logger.debug("Including [" + getUrl() + "]");
					}
					rd.include(request, response);
				}

				else {
					// Note: The forwarded resource is supposed to determine the content type itself.
					if (logger.isDebugEnabled()) {
						logger.debug("Forwarding to [" + getUrl() + "]");
					}
					//转发
					rd.forward(request, response);
				}
			
			}
		}	

RequestDispatcher//拿到转发器

				源码:
				package javax.servlet;
				//原生servlet的转发器
				public interface RequestDispatcher {
				}

你可能感兴趣的:(SpringBoot的SpringMVC视图解析器源码学习笔记)