SpringMVC源码浅析(SpringMVC执行流程)

SpringMVC DispatcherServlet执行流程及源码分析 你要知道的SpringMVC DispatcherServlet执行流程及源码分析都在这里转载请注明出处 http://www.jianshu.com/p/0f981efdfbbd本系列文章主要根据源码讲解SpringMVC的启动过程,以及相关重要组件的源码分析。阅读此系列文章需要具备Spring以及SpringMVC相关知识。本文将分以下几篇文章进行讲解,读者可按需查阅。 SpringMVC 启动 阅读详情

一. DispatchServlet源码结构



二. SpringMVC执行流程

 

三. 走入源码

1. DispatchServlet初始化

        创建bean对象: 传统mvc项目通过xml添加DispatchServlet的bean, SpringBoot中通过DispatcherServletAutoConfiguration添加DispatchServlet的bean. 

        初始化: 项目没有设置loadOnStartup则待第一次到来时才开始初始化, 设置了loadOnStartup值则随容器启动时完成初始化. 初始化核心代码入口 onRefresh()

1.1 onRefresh()

	protected void onRefresh(ApplicationContext context) {
		initStrategies(context);
	}

	/**
	 * Initialize the strategy objects that this servlet uses.
	 * <p>May be overridden in subclasses in order to initialize further strategy objects.
	 */
	protected void initStrategies(ApplicationContext context) {
		initMultipartResolver(context);
		initLocaleResolver(context);
		initThemeResolver(context);
        // 初始化处理器映射器
		initHandlerMappings(context);
        // 处理华处理器适配器
		initHandlerAdapters(context);
        // 初始化异常处理器
		initHandlerExceptionResolvers(context);
		initRequestToViewNameTranslator(context);
        // 初始化视图解析器
		initViewResolvers(context);
		initFlashMapManager(context);
	}

        其他处理器不是核心处理器, 不展开讲, 下面以初始化处理器适配器看下初始化做了什么, 其他处理器初始化大同小异

1.2 initHandlerMappings()

    private void initHandlerMappings(ApplicationContext context) {
		this.handlerMappings = null;
        // 是否查找出所有的处理器映射器, 默认值为true
		if (this.detectAllHandlerMappings) {
            // 递归查找出所有处理器映射器
			Map<String, HandlerMapping> matchingBeans =
					BeanFactoryUtils.beansOfTypeIncludingAncestors(context, HandlerMapping.class, true, false);
			if (!matchingBeans.isEmpty()) {
				this.handlerMappings = new ArrayList<>(matchingBeans.values());
				AnnotationAwareOrderComparator.sort(this.handlerMappings);
			}
		}else {
			try {
                // 获取指定beanName的处理器映射器
				HandlerMapping hm = context.getBean(HANDLER_MAPPING_BEAN_NAME, HandlerMapping.class);
				this.handlerMappings = Collections.singletonList(hm);
			}
			catch (NoSuchBeanDefinitionException ex) {}
		}
		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");
			}
		}
        // 设置parseRequestPath的值
		for (HandlerMapping mapping : this.handlerMappings) {
			if (mapping.usesPathPatterns()) {
				this.parseRequestPath = true;
				break;
			}
		}
	}

        这里通过getDefaultStrategies()  或 getDefaultStrategy() 方法获取多个或一个默认的处理器

1.2.1 getDefaultStrategies()

	protected <T> List<T> getDefaultStrategies(ApplicationContext context, Class<T> strategyInterface) {
		if (defaultStrategies == null) {
			try {
				ClassPathResource resource = new ClassPathResource(DEFAULT_STRATEGIES_PATH, DispatcherServlet.class);
                // 加载sping-webmvc下的 DispatcherServlet.properties文件
				defaultStrategies = PropertiesLoaderUtils.loadProperties(resource);
			}
			catch (IOException ex) {
				throw new IllegalStateException("Could not load '" + DEFAULT_STRATEGIES_PATH + "': " + ex.getMessage());
			}
		}

		String key = strategyInterface.getName();
		String value = defaultStrategies.getProperty(key);
		if (value != null) {
			String[] classNames = StringUtils.commaDelimitedListToStringArray(value);
			List<T> strategies = new ArrayList<>(classNames.length);
			for (String className : classNames) {
				try {
					Class<?> clazz = ClassUtils.forName(className, DispatcherServlet.class.getClassLoader());
                    // 创建出bean对象加到列表中返回
					Object strategy = createDefaultStrategy(context, clazz);
					strategies.add((T) strategy);
				}
				catch (ClassNotFoundException ex) {
					throw new BeanInitializationException(
							"Could not find DispatcherServlet's default strategy class [" + className +
							"] for interface [" + key + "]", ex);
				}
				catch (LinkageError err) {
					throw new BeanInitializationException(
							"Unresolvable class definition for DispatcherServlet's default strategy class [" +
							className + "] for interface [" + key + "]", err);
				}
			}
			return strategies;
		}
		else {
			return Collections.emptyList();
		}
	}

        DispatcherServlet.properties文件如下

2. SpringMVC执行流程

        核心代码入口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 {
                // 1. 检测是否为多媒体文件, 是则解析多媒体文件
				processedRequest = checkMultipart(request);
				multipartRequestParsed = (processedRequest != request);

				// Determine handler for the current request.
                // 2. 获取处理器, 返回处理器执行链(包含处理器和拦截器列表)
				mappedHandler = getHandler(processedRequest);
				if (mappedHandler == null) {
					noHandlerFound(processedRequest, response);
					return;
				}

				// 3. 获取处理器适配器
				HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

				String method = request.getMethod();
				boolean isGet = HttpMethod.GET.matches(method);
				if (isGet || HttpMethod.HEAD.matches(method)) {
					long lastModified = ha.getLastModified(request, mappedHandler.getHandler());
					if (new ServletWebRequest(request, response).checkNotModified(lastModified) && isGet) {
						return;
					}
				}

                // 执行拦截器前置处理
				if (!mappedHandler.applyPreHandle(processedRequest, response)) {
					return;
				}

				// 4. 执行处理器方法
				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) {scenarios.
				dispatchException = new NestedServletException("Handler dispatch failed", err);
			}
            // 5. 结果处理(进行异常处理 和 视图渲染)
			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()) {
				if (mappedHandler != null) {
					mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
				}
			}
			else {
				if (multipartRequestParsed) {
					cleanupMultipart(processedRequest);
				}
			}
		}
	}

2.1 getHandler()

	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;
	}

2.1.1 getHandler()   AbstractHandlerMapping内的方法

	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 = obtainApplicationContext().getBean(handlerName);
		}

		// Ensure presence of cached lookupPath for interceptors and others
		if (!ServletRequestPathUtils.hasCachedPath(request)) {
			initLookupPath(request);
		}

        // 获取拦截器列表, 包装成处理器执行链返回
		HandlerExecutionChain executionChain = getHandlerExecutionChain(handler, request);

		if (logger.isTraceEnabled()) {
			logger.trace("Mapped to " + handler);
		}
		else if (logger.isDebugEnabled() && !DispatcherType.ASYNC.equals(request.getDispatcherType())) {
			logger.debug("Mapped to " + executionChain.getHandler());
		}

		if (hasCorsConfigurationSource(handler) || CorsUtils.isPreFlightRequest(request)) {
			CorsConfiguration config = getCorsConfiguration(handler, request);
			if (getCorsConfigurationSource() != null) {
				CorsConfiguration globalConfig = getCorsConfigurationSource().getCorsConfiguration(request);
				config = (globalConfig != null ? globalConfig.combine(config) : config);
			}
			if (config != null) {
				config.validateAllowCredentials();
			}
			executionChain = getCorsHandlerExecutionChain(request, executionChain, config);
		}

		return executionChain;
	}

        getHandlerInternal(request)为 各个HandlerMapping实现类的方法, 通过请求路径/@RequestMapping注解等匹配, 找到匹配的处理器方法返回

2.2 getHandlerAdapter()

	protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
		if (this.handlerAdapters != null) {
			for (HandlerAdapter adapter : this.handlerAdapters) {
				if (adapter.supports(handler)) {
					return adapter;
				}
			}
		}
		throw new ServletException("No adapter for handler [" + handler +
				"]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
	}

2.3 handle() 

        该方法为具体的处理器适配的的代码, 下面举例两个常见适配器的实现源码

SimpleControllerHandlerAdapter的实现
	public ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		return ((Controller) handler).handleRequest(request, response);
	}
RequestMappingHandlerAdapter的实现
	// 父类AbstractHandlerMethodAdapter内的方法
    public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {

		return handleInternal(request, response, (HandlerMethod) handler);
	}
	// HttpRequestHandlerAdapter内代码
    protected ModelAndView handleInternal(HttpServletRequest request,
			HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {

		ModelAndView mav;
		checkRequest(request);

		// Execute invokeHandlerMethod in synchronized block if required.
		if (this.synchronizeOnSession) {
			HttpSession session = request.getSession(false);
			if (session != null) {
				Object mutex = WebUtils.getSessionMutex(session);
				synchronized (mutex) {
					mav = invokeHandlerMethod(request, response, handlerMethod);
				}
			}
			else {
				// 执行处理器方法
				mav = invokeHandlerMethod(request, response, handlerMethod);
			}
		}
		else {
			// 执行处理器方法
			mav = invokeHandlerMethod(request, response, handlerMethod);
		}

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

		return mav;
	}
	protected ModelAndView invokeHandlerMethod(HttpServletRequest request,
			HttpServletResponse response, HandlerMethod handlerMethod) throws Exception {
        // 1. 构建web请求对象
		ServletWebRequest webRequest = new ServletWebRequest(request, response);
		try {
            // 2. 获取数据绑定工厂
			WebDataBinderFactory binderFactory = getDataBinderFactory(handlerMethod);
			ModelFactory modelFactory = getModelFactory(handlerMethod, binderFactory);
            // 3. 包装成可执行的处理器方法对象
			ServletInvocableHandlerMethod invocableMethod = createInvocableHandlerMethod(handlerMethod);
            // 4. 设置参数解析器
			if (this.argumentResolvers != null) {
				invocableMethod.setHandlerMethodArgumentResolvers(this.argumentResolvers);
			}
            // 5. 设置返回值处理器
			if (this.returnValueHandlers != null) {
				invocableMethod.setHandlerMethodReturnValueHandlers(this.returnValueHandlers);
			}
			invocableMethod.setDataBinderFactory(binderFactory);
            // 6. 设置参数名解析器
			invocableMethod.setParameterNameDiscoverer(this.parameterNameDiscoverer);
            // 7. 创建ModelAndView容器
			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 asyncManager = WebAsyncUtils.getAsyncManager(request);
			asyncManager.setTaskExecutor(this.taskExecutor);
			asyncManager.setAsyncWebRequest(asyncWebRequest);
			asyncManager.registerCallableInterceptors(this.callableInterceptors);
			asyncManager.registerDeferredResultInterceptors(this.deferredResultInterceptors);

			if (asyncManager.hasConcurrentResult()) {
				Object result = asyncManager.getConcurrentResult();
				mavContainer = (ModelAndViewContainer) asyncManager.getConcurrentResultContext()[0];
				asyncManager.clearConcurrentResult();
				LogFormatUtils.traceDebug(logger, traceOn -> {
					String formatted = LogFormatUtils.formatValue(result, !traceOn);
					return "Resume with async result [" + formatted + "]";
				});
				invocableMethod = invocableMethod.wrapConcurrentResult(result);
			}

            // 8. 执行处理器方法调用 (核心代码)
			invocableMethod.invokeAndHandle(webRequest, mavContainer);
			if (asyncManager.isConcurrentHandlingStarted()) {
				return null;
			}
            
            // 9. 包装ModelAndView对象返回
			return getModelAndView(mavContainer, modelFactory, webRequest);
		}
		finally {
			webRequest.requestCompleted();
		}
	}

        RequestMappingHandlerAdapter的核心代码在invocableMethod.invokeAndHandle(webRequest, mavContainer); 该方法会完成参数解析并绑定, 执行处理器方法, 返回值解析等操作, 这里不展开讲, 之后再写一篇RequestMappingHandlerAdapter源码解析的文章

2.4 processDispatchResult()

 DispatcherServlet内代码

	private void processDispatchResult(HttpServletRequest request, HttpServletResponse response,
			@Nullable HandlerExecutionChain mappedHandler, @Nullable ModelAndView mv,
			@Nullable Exception exception) throws Exception {

		boolean errorView = false;

		if (exception != null) {
			if (exception instanceof ModelAndViewDefiningException) {
				logger.debug("ModelAndViewDefiningException encountered", exception);
				mv = ((ModelAndViewDefiningException) exception).getModelAndView();
			}
			else {
				Object handler = (mappedHandler != null ? mappedHandler.getHandler() : null);            
                // 1. 异常处理
				mv = processHandlerException(request, response, handler, exception);
				errorView = (mv != null);
			}
		}

		// Did the handler return a view to render?
		if (mv != null && !mv.wasCleared()) {
            // 2. 获取视图对象并完成渲染
			render(mv, request, response);
			if (errorView) {
				WebUtils.clearErrorRequestAttributes(request);
			}
		}
		else {
			if (logger.isTraceEnabled()) {
				logger.trace("No view rendering, null ModelAndView returned.");
			}
		}

		if (WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {
			// Concurrent handling started during a forward
			return;
		}

		if (mappedHandler != null) {
			// Exception (if any) is already handled..
			mappedHandler.triggerAfterCompletion(request, response, null);
		}
	}

拓展: 需要了解更加具体的流程, 推荐阅读 Spring MVC源码分析

SpringMVC执行流程及源码解析 原文链接 谢谢各位点赞评论收藏~自己学习时候记录的东西,没想到能被关注~自己理解还不太好,希望各位看的时候不要全部按照文章里写的来,要自己思考一下,如有不对还请指出,只希望不会误导别人。 在SpringMVC中主要是围绕着DispatcherServlet来设计,可以把它当做指挥中心。这里先说明一下SpringMVC文档给出的执行流程,然后是我们稍微具体的执行流程,最后是流程大致的源码跟... 阅读详情

相关推荐

SAP FICO会计凭证过账接口

-------------------------------------增加职能范围-ZHANGZG-2022.09.07 注释掉-2022.09.20。CONCATENATE '总账' ls_doc_item-hkont '要求输入成本对象值!*-------------------------------------增加职能范围-ZHANGZG-2022.09.07。*-------------------------------------增加职能范围-ZHANGZG-2022.09.07。

dingqing86的专栏 1078

springboot启动(六)——onRefresh()方法,内嵌web容器(tomcat)启动

onRefresh()方法执行作用 之前文章跟着代码依然可知,当前系统已加载了所有得bean得定义信息,包括自动配置得类 1、进入方法createEmbeddedServletContainer private void createEmbeddedServletContainer() { EmbeddedServletContainer localContainer = this.embeddedServletContainer; ServletContext localServletCo

luoxiaomei999的博客 1457

XGBoost调参新姿势:Bayesian优化实战指南(附完整代码)

本文详细介绍了如何使用Bayesian优化方法高效调优XGBoost模型参数。通过解析Bayesian优化核心原理和XGBoost关键参数,提供完整的实战代码示例,帮助读者掌握这一智能调参技术,显著提升模型性能。文章特别适合机器学习工程师和数据科学家阅读。

weixin_42536058的博客 366

Spring中refresh分析之onRefresh方法详解

接上文[Spring中refresh分析之initApplicationEventMulticaster方法详解](https://blog.youkuaiyun.com/J080624/article/details/72832401)我们分析过initApplicationEventMulticaster后,本文分析onRefresh方法。 首先调用父类的方法初始化主题源(themeSource)然后创建WebServer。SpringBoot内置的Tomcat或者UndertowWebServer就是在这里实.

小小默:进无止境 5917

磁编码器选型避坑指南:为什么MT6816比霍尔传感器更适合你的伺服系统?

本文深入对比了MT6816磁编码器与传统霍尔传感器在伺服系统中的应用。MT6816基于AMR技术,对磁场方向敏感而非强度,具备高精度、强抗干扰、高安装容差和极低延时等优势,尤其适合高转速、恶劣环境下的工业场景,能有效提升系统可靠性与长期稳定性。

rainy的博客 1102

[GXYCTF2019]BabyUpload1 -- .htaccess文件解析与蚁剑实战指南

本文深入解析了[GXYCTF2019]BabyUpload1文件上传漏洞的实战利用。通过绕过后缀名与内容检测,上传包含PHP代码的.jpg文件,并利用.htaccess文件强制服务器将其解析为PHP脚本。文章详细介绍了.htaccess的原理、构造方法、Content-Type绕过技巧,并演示了如何使用中国蚁剑连接Webshell获取Flag,为Web安全学习提供了完整实战指南。

weixin_29016315的博客 507

springmvc源码解析(二),DispatcherServlet加载的过程

文章目录onRefresh刷新dispatcherservlet九大组件的主要地方initMultipartResolver 初始化文件上传解析器initLocaleResolver本地化解析getDefaultStrategy方法获取默认配置(缺省策略)initHandlerMappings处理器映射器 保存Url映射关系(重要) 在讲initWebApplicationContext方法的时候,分为两部分,一部分是创建web端的spring容器,一部分是DispatcherServlet的加载,前面一篇

你就像甜甜的益达 757

使用Qt Creator调用eBUS SDK

在新界面,勾选左下角“ Show unreachable Network Devices",可以看到没有成功连接的网络相机,原因是IP地址配置错误。每个版本的OpenCV的依赖项的名字都不同,我这里是opencv_world490.lib与opencv_world490d.lib。函数,可以看到在这里是图像缓存区,能够对捕获的图像进行一些操作。在Visual Studio打开项目属性,在VC++目录这里,把Opencv的路径添加进去。这时,会自动跳转到mainwindow.cpp,生成该按钮对应的槽函数。

qq_35685051的博客 1287

Spring源码 - 容器刷新#onRefresh()

Spring源码 - 容器刷新#onRefresh()

目目沐沐 5万+

【STM32项目】基于Stm32c8t6-镭射激光打印机的设计(完整工程资料源码)

随着打印技术的快速发展,镭射打印技术也开始得到越来越广泛的应用。这种技术可以被用于在木材、塑料、皮革、织物等各种材料上进行图形打印,并且通常比传统机器更快、更准确和更灵活。

嵌入式技术开发 7198

大数据领域数据架构的工业互联网数据架构设计

工业互联网作为第四次工业革命的重要驱动力,正在深刻改变传统制造业的生产方式和商业模式。本文旨在探讨工业互联网环境下的大数据架构设计,重点解决工业数据采集、传输、存储、处理和分析等关键环节的技术挑战。工业互联网数据架构的核心组件大数据技术在工业场景下的应用数据治理和质量控制边缘计算与云计算的协同架构背景介绍:建立基本概念和问题域核心架构:详细解析工业互联网数据架构技术实现:通过代码和数学模型展示关键技术实践案例:展示真实场景应用工具资源:推荐实用开发工具和学习资源。

软件工程实践的博客 855

Spring源码之六-onRefresh()方法

今天带大家解读Spirng源码之六的onRefresh()方法,这是refresh()的其中的一个方法,看似是一个空方法,实则他是非常非常重要的,对于提高Spring的扩展性。

程序员田同学的博客 1839

Altium Designer应用技巧1: 功能模块的复用方法

Altium Designer应用技巧1: 功能模块的复用方法      我们在使用Altium Designer进行电路图设计时,常会遇到功能模块的复用问题,例如我们经常需要将12V以DC-DC的方式转换成5V,这在很多线路板上都会应用到。现在我们普通的做法是,每个板子都重新绘制一遍,像这样DC-DC的电路,很浪费时间。那么如何采用提高工作效率呢?我们可以采取Altium Desi

snmplink的博客 1万+

SpringMVC执行流程源码浅析

这么文章主要介绍两个问题: 1、什么是mvc 2、springmvc的主要执行流程 1、什么是mvc MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。...

莫失莫忘的博客 302

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

一篇文章搞懂SpringMVC执行流程(超详细易懂源码流程)

SpringMVC源码执行流程?一个完整的请求响应在MVC中是什么样的?用户访问 /user/info 时后台发生了什么?M-V-C分别在哪?

2301_80835121的博客 2718

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

SpringMVC的执行流程剖析和源码跟踪

doDispatch 是 Spring MVC 框架中的核心方法,用于处理 HTTP 请求并将其分发到相应的处理器(Handler)。它是 DispatcherServlet 的关键部分,负责协调请求的整个生命周期,包括请求解析、处理器选择、视图渲染和异常处理。如果请求是多部分请求,则调用 cleanupMultipart 方法清理相关资源。如果请求是异步的,则直接返回,后续由异步机制继续处理。

小Ti博客 1678

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

SpringMVC源码解析(二):请求执行流程

前文中我们介绍了SpringMVC容器的启动,包括前端控制器DispatcherServlet对象的创建,过滤器添加到Tomcat容器的过滤器集合中,将所有拦截器、跨域配置、消息转换器等配置统一添加到各自集合中,解析@RequestMapping注解生成请求路径和Controller方法的映射map。本章来研究下请求的执行过程。说到请求过程,那么得先说下入口在哪里?入口肯定是统一分发请求给处理程序的,DispatcherServlet归根结底也是Servlet。

从基础到源码解析的学习记录 1万+

【SpringMVC】| SpringMVC执行流程(含源码分析)

【SpringMVC】| SpringMVC执行流程(含源码分析)

m0_61933976的博客 5399

SpringMVC源码剖析-SpringMVC执行流程

前言 上一篇文章写得是SpringMVC组件初始化,这篇文章我们来探讨一下SpringMVC的执行流程 SpringMVC执行流程 SpringMVC执行流程几乎是在面试时面试官对SpringMVC部分的必问之题,下面是SpirngMVC的执行原理图 这个是请求在SpringMVC的执行流程 DispatcherServlet:请求打过来由DispatcherServlet处理,它是 SpringMVC 中的前端控制器(中央控制器), 负责接收 Request 并将 Request 转发给对应的处理组件

墨家巨子@俏如来 6116

从源码角度分析SpringMVC执行流程

SpringMVC是基于Servlet进行的封装框架,是一个Spring框架的一个模块。它以SpringIOC容器为基础,并利用容器的特性来简化它的配置,所以 SpringMVC 和 Spring 可直接整合使用。SpringMVC也是一个容器,使用IoC核心技术,管理界面层中的控制器对象。SpringMVC的底层就是servlet,以servlet为核心,接收请求、处理请求,显示处理结果给用户。

qq_45794852的博客 1082

SpringMVC的执行流程与源码分析

SpringMVC概述。

weixin_63975657的博客 2948

面试经典问题SpringMVC执行流程(源码解读剖析)

SpringMVC执行流程最优解!

奈何的人生 2638

springMVC执行流程详解

再进入这个render方法里面,可以发现这个视图解析器会对这个视图进行一个具体的解析,并且会将解析的view返回给这个DispatcherServlet里面,最终会将这个数据进行一个转发或者重定向,对这个view进行一个渲染,最终响应到这个客户端。2,前端控制器会通过这个HandlerMapping处理器映射器,找到合适的处理器,就是通过这个输入的url,找到对应的handler。3,进入这个**doDispatch()**方法里面,可以看到以下几行代码,主要是来返回这个处理器执行链,处理器适配器等操作。.

band_mmbx的博客 1万+

【SpringMVC】源码解读-执行流程

这里我们看到,它通过遍历处理链当中的拦截器集合,执行拦截器当中的preHandle方法,如果所有都返回true,那么拦截器下标就会是拦截器个数-1,如果其中一个返回了false,就会去执行triggerAfterCompletion方法,也就是执行已经执行过的拦截器的AfterCompletion方法。的类,在上面,我们说过,这个类,其实就是保存了Controller的BeanName和请求路径对应的类中的方法。这个方法最终简化后,也就是执行这个方法,点进去之后我们会发现这是一个空的方法,但是。

shenqibaobao的博客 952

【阅读SpringMVC源码】调试观察验证SpringMVC执行流程

【阅读SpringMVC源码】调试观察验证SpringMVC执行流程

伟庭的博客 968

SpringMVC执行流程

Ø 第三步:处理器映射器HandlerMapping向前端控制器返回Handler,HandlerMapping会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器对象,多个HandlerInterceptor拦截器对象),通过这种策略模式,很容易添加新的映射策略。Ø 第八步:前端控制器请求视图解析器去进行视图解析 (根据逻辑视图名解析成真正的视图),通过这种策略很容易更换其他视图技术,只需要更改视图解析器即可。主要是适配注解类处理器,注解类处理器就是我们经常使用的。

jyx_boy的博客 2005
上一篇: Spring Aop源码流程图
下一篇: @DateTimeFormat失效原因
陈*^_^*
博客等级 码龄6年 48粉丝 16原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值