首页 / 体育 / CBA / 正文

flash源码(SpringMVC流程及源码分析)

放大字体  缩小字体 来源:超贝 2026-04-17 17:38  浏览次数:16

学了一遍SpringMVC以后,想着做一个总结,复习一下。复习写下面的总结的时候才发现,其实自己学得并不彻底、牢固、也没有学全,视频跟书本是要结合起来一起,每一位老师的视频可能提到的东西都不一致,也导致也不是很全面,书本上会讲的笔记系统、全面。同时我自己也是一个初学者,下面总结的可能并不完善、正确,希望看到的大神给我指出,在此非常感谢。


Spring Web MVC (下文简称为 SpringMVC )是 Spring 提供 Web 应用的框架设计,属于表现层的框架。SpringMVC是Spring框架的一部分。
Spring框架包括大致六大模块,核心容器(Core Container)、AOP和设备支持、数据访问及集成、Web、报文发送、Test

https://docs.spring.io/spring-framework/docs/5.0.0.M5/spring-framework-reference/html/overview.html#overview-modules

挺奇怪这个图是哪里来的?(路过的大神请指点)

拷贝以上信息:

Version 5.2.13.RELEASE

Overview

Core

Testing

Data Access

Web Servlet

Web Reactive

Integration

Languages

按照以上信息的Web Servlet、Web Reactive已经是分属于不同的模块了。

  • Web Servlet:Spring MVC, WebSocket, SockJS, STOMP Messaging.
  • Web Reactive:Spring WebFlux, WebClient, WebSocket.

上面提到了Spring有不同的版本,在此记录一下各个版本的意义。

说明

Snapshot

尚不稳定,仍处于开发中的版本

稳定版

GA

代表广泛可用的稳定版(General Availability)

里程碑版

RC

Release Candidate(最终测试),即将作为正式版发布

二、SpringMVC流程及原理

1、执行流程

图片来源:三、引用参考资料

1.1、执行流程

  • 01、用户发送出请求到前端控制器(中央处理器)DispatcherServlet进行处理。
  • 02、前端控制器DispatcherServlet收到请求后,调用处理器映射器HandlerMapping。
  • 03、处理器映射器HandlerMapping(处理器映射器)根据request请求的URL等信息查找能够进行处理的Handler,以及相关拦截器interceptor,并构造HandlerExecutionChain执行链,然后将构造好的HandlerExecutionChain执行链对象返回给前端控制器DispatcherServlet。
  • 04、前端控制器DispatcherServlet根据处理器映射器HandlerMapping的
  • 05、处理器适配器HandlerAdapter经过适配调用具体的处理器(Handler/Controller),即业务中自己写的Controller。
  • 06、Controller处理完后返回ModelAndView(springmvc的封装对象,将model和view封装在一起)给处理器适配器HandlerAdapter;
  • 07、处理器适配器HandlerAdapter将Controller执行结果ModelAndView返回给前端控制器DispatcherServlet。
  • 08、前端控制器DispatcherServlet调用视图解析器ViewReslover处理ModelAndView。
  • 09、视图解析器ViewReslover解析后根据逻辑视图名解析成物理视图名即具体的页面地址,生成并返回具体对象View(springmvc封装对象,是一个接口)。
  • 10、前端控制器DispatcherServlet根据对象View进行视图渲染,填充Model。
  • 11、前端控制器DispatcherServlet向用户返回响应

1.2、执行流程说明:

1.2.1、第02、03说明

(2) 处理器映射器作用:根据请求,从springmvc容器对象中获取处理器对象(MyController controller = ctx.getBean("some")

(4) HandlerExecutionchain:类中保存着
a:处理器对象(MyController);
b:项目中的所有的拦截器List

(1) HandlerExecutionChain执行链找到对应的处理器映射器HandlerAdapter。
(2) 处理器适配器:springmvc框架中的对象,需要实现HandlerAdapter接口,
(3) 处理器适配器作用:执行处理器方法(调用MyController.doSome()得到返回值ModelAndView )
(4) 前端控制器中调用适配器:HandlerAdapter ha =getHandlerAdapter (mappedHandler.getHandler());
(5) 执行处理器方法:mv= ha.handle (processedRequest, response, mappedHandler.getHandler());

InternalResourceview:视图类,表示jsp文件,视图解析器会创建InternalResourceView类对象。 这个对象的里面,有一个属性url-/WEB-INF/view/show.jsp

1.2.2、SpringMVC组件说明

  • (1). 前端控制器(DispatcherServlet):接收请求,响应结果,相当于电脑的CPU。
  • (2). 处理器映射器(HandlerMapping):根据URL去查找处理器.
  • (3). 处理器(Handler):(需要程序员去写代码处理逻辑的).
  • (4). 处理器适配器(HandlerAdapter):会把处理器包装成适配器,这样就可以支持多种类型的处理器,类比笔记本的适配器(适配器模式的应用).
  • (5). 视图解析器(ViewResovler):进行视图解析,多返回的字符串,进行处理,可以解析成对应的页面.

1.2.3、SpringMVC详细流程图


图片来源:三、引用参考资料

二、源码分析

ApplicationContext初始化入口类:ApplicationObjectSupport的setApplicationContext方法,setApplicationContext方法中核心部分就是初始化容器initApplicationContext(context),子类AbstractDetectingUrlHandlerMapping实现了该方法。
类图:


RequestMappingHandlerMapping ,用于注解@Controller,@RequestMapping来定义controller.
初始化时,3个类的大致分工如下:

  • AbstractHandlerMethodMapping定义整个算法流程;
  • RequestMappingInfoHandlerMapping提供匹配条件RequestMappingInfo的解析处理;
  • RequestMappingHandlerMapping根据@RequestMapping注解生成 RequestMappingInfo,同时提供isHandler实现

2、前端控制器(中央处理器)DistepcherServlet

org.springframework.web.servlet.frameworkServlet.service(HttpServletRequest request, HttpServletResponse response)

	@Override	protected void service(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());		if (httpMethod == HttpMethod.PATCH || httpMethod == null) {			processRequest(request, response);		}		else {			super.service(request, response);		}	}

doGet()又调用frameworkServlet类中的processRequest(request, response);

	protected final void processRequest(HttpServletRequest request, HttpServletResponse response)			throws ServletException, IOException {		long startTime = System.currentTimeMillis();		Throwable failureCause = null;		LocaleContext previousLocaleContext = LocaleContextHolder.getLocaleContext();		LocaleContext localeContext = buildLocaleContext(request);		RequestAttributes previousAttributes = RequestContextHolder.getRequestAttributes();		ServletRequestAttributes requestAttributes = buildRequestAttributes(request, response, previousAttributes);		WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);		asyncManager.registerCallableInterceptor(frameworkServlet.class.getName(), new RequestBindingInterceptor());		initContextHolders(request, localeContext, requestAttributes);		try {			doService(request, response);		}		catch (ServletException | IOException ex) {			failureCause = ex;			throw ex;		}		catch (Throwable ex) {			failureCause = ex;			throw new NestedServletException("Request processing failed", ex);		}		finally {			resetContextHolders(request, previousLocaleContext, previousAttributes);			if (requestAttributes != null) {				requestAttributes.requestCompleted();			}			logResult(request, response, failureCause, asyncManager);			publishRequestHandledEvent(request, response, startTime, failureCause);		}	}

源码来源:

查看DispatcherServlet中的doService(HttpServletRequest request, HttpServletResponse response)方法

	@Override	protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {		logRequest(request);		// Keep a snapshot of the request attributes in case of an include,		// to be able to restore the original attributes after the include.		Map<String, Object> attributesSnapshot = null;		if (WebUtils.isIncludeRequest(request)) {			attributesSnapshot = new HashMap<>();			Enumeration<?> attrNames = request.getAttributeNames();			while (attrNames.hasMoreElements()) {				String attrName = (String) attrNames.nextElement();				if (this.cleanupAfterInclude || attrName.startsWith(DEFAULT_STRATEGIES_PREFIX)) {					attributesSnapshot.put(attrName, request.getAttribute(attrName));				}			}		}		// Make framework objects available to handlers and view objects.		request.setAttribute(WEB_APPLICATION_CONTEXT_ATTRIBUTE, getWebApplicationContext());		request.setAttribute(LOCALE_RESOLVER_ATTRIBUTE, this.localeResolver);		request.setAttribute(THEME_RESOLVER_ATTRIBUTE, this.themeResolver);		request.setAttribute(THEME_SOURCE_ATTRIBUTE, getThemeSource());		if (this.flashMapManager != null) {			FlashMap inputFlashMap = this.flashMapManager.retrieveAndUpdate(request, response);			if (inputFlashMap != null) {				request.setAttribute(INPUT_FLASH_MAP_ATTRIBUTE, Collections.unmodifiableMap(inputFlashMap));			}			request.setAttribute(OUTPUT_FLASH_MAP_ATTRIBUTE, new FlashMap());			request.setAttribute(FLASH_MAP_MANAGER_ATTRIBUTE, this.flashMapManager);		}		try {			doDispatch(request, response);		}		finally {			if (!WebAsyncUtils.getAsyncManager(request).isConcurrentHandlingStarted()) {				// Restore the original attribute snapshot, in case of an include.				if (attributesSnapshot != null) {					restoreAttributesAfterInclude(request, attributesSnapshot);				}			}		}	}

可以看出doDispatch()就是SpringMVC的核心代码了,分析doDispatch():

2.1、查找处理器映射器HandlerMapping

doDispatch()关键代码:

HandlerExecutionChain mappedHandler = null;mappedHandler = getHandler(processedRequest);

调试代码如下:

接着看getHandler(HttpServletRequest request)方法,先遍历HandlerMappers,查找控制器找到之后就返回执行链HandlerExecutionChain类型的Handler。


将正在调试的idea打开自己编写的Controller来对照,发现一致:

2.2、根据处理器映射器HandlerMapping返回结果调用处理器适配器HandlerAdapter

源码如下:

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


查看DEBUG调试模式中getHandlerAdapter()方法在中的:
handler、adapter、this.handlerAdapters

adapter

adapter = {RequestMappingHandlerAdapter@4827}  customArgumentResolvers = null argumentResolvers = {HandlerMethodArgumentResolverComposite@4833}  initBinderArgumentResolvers = {HandlerMethodArgumentResolverComposite@4834}  customReturnValueHandlers = null returnValueHandlers = {HandlerMethodReturnValueHandlerComposite@4835}  modelAndViewResolvers = null contentNegotiationManager = {ContentNegotiationManager@4836}  messageConverters = {ArrayList@4837}  size = 4 requestResponseBodyAdvice = {ArrayList@4838}  size = 0 webBindingInitializer = null taskExecutor = {SimpleAsyncTaskExecutor@4839}  asyncRequestTimeout = null callableInterceptors = {CallableProcessingInterceptor[0]@4840}  deferredResultInterceptors = {DeferredResultProcessingInterceptor[0]@4842}  reactiveAdapterRegistry = {ReactiveAdapterRegistry@4844}  ignoreDefaultModelonRedirect = false cacheSecondsForSessionAttributeHandlers = 0 synchronizeOnSession = false sessionAttributeStore = {DefaultSessionAttributeStore@4845}  parameterNameDiscoverer = {DefaultParameterNameDiscoverer@4846}  beanFactory = {DefaultListableBeanFactory@4847} "org.springframework.beans.factory.support.DefaultListableBeanFactory@56b5a4c3: defining beans [myController,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,org.springframework.context.event.internalEventListenerProcessor,org.springframework.context.event.internalEventListenerFactory,org.springframework.web.servlet.view.InternalResourceViewResolver#0]; root of factory hierarchy" sessionAttributesHandlerCache = {ConcurrentHashMap@4848}  size = 0 initBinderCache = {ConcurrentHashMap@4849}  size = 0 initBinderAdviceCache = {linkedHashMap@4850}  size = 0 modelAttributeCache = {ConcurrentHashMap@4851}  size = 0 modelAttributeAdviceCache = {linkedHashMap@4852}  size = 0 order = 2147483647 supportedMethods = null allowHeader = "GET,HEAD,POST,PUT,PATCH,DELETE,OPTIONS" requireSession = false cacheControl = null cacheSeconds = -1 varyByRequestHeaders = null useExpiresHeader = false useCacheControlHeader = true useCacheControlNoStore = true alwaysMustRevalidate = false servletContext = {ApplicationContextFacade@4754}  logger = {LogAdapter$JavaUtilLog@4854}  applicationContext = {XmlWebApplicationContext@4665} "WebApplicationContext for namespace 'myweb-servlet', started on Tue Mar 02 23:25:35 CST 2021" messageSourceAccessor = {MessageSourceAccessor@4855} 

可以看到找到4个处理器适配器。通过DEBUG模式可以看到,此次取到的处理器适配器HandlerAdapter是:RequestMappingHandlerAdapter

ha = {RequestMappingHandlerAdapter@4827} 

2.3、检查拦截器Interceptor

applyPreHandle(processedRequest, response)源码:

	boolean applyPreHandle(HttpServletRequest request, HttpServletResponse response) throws Exception {		HandlerInterceptor[] interceptors = getInterceptors();		if (!ObjectUtils.isEmpty(interceptors)) {			for (int i = 0; i < interceptors.length; i++) {				HandlerInterceptor interceptor = interceptors[i];				if (!interceptor.preHandle(request, response, this.handler)) {					triggerAfterCompletion(request, response, null);					return false;				}				this.interceptorIndex = i;			}		}		return true;	}

2.3、处理器适配器HandlerAdapter执行Handler(Controller)返回ModelAndView

DEBUG模式调试,是调到了:
org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter#handle
源码如下:

	@Override	@Nullable	public final ModelAndView handle(HttpServletRequest request, HttpServletResponse response, Object handler)			throws Exception {		return handleInternal(request, response, (HandlerMethod) handler);	}

注意,handleInternal(request, response, (HandlerMethod) handler)方法的返回值是ModelAndView ,这里就完成了处理器适配器HandlerAdapter执行Handler(Controller)并将结果ModelAndView返回给前端控制器DistepchServlet

2.4、视图解析器ViewResolver

总结一下:
视图解析器ViewResolver接口主要作用是解析前端控制器DispatcherServlet传递的逻辑视图名,并将解析结果的真正的视图对象View传回给前端控制器DispatcherServlet


ViewResolver的UML:

2.5、视图View

2.5.1、视图对象的作用

  • (1)、将控制器返回的数据处理渲染,最终返回客户端展示给用户,主要就是完成转发或者是重定向的操作.。
  • (2)、为了实现视图模型和具体实现技术的解耦(指的是Spring在org.springframework.web.servlet包中定义的抽象View接口),详见2.5.2View接口图。
  • (3)、视图对象View由视图解析器负责实例化。由于视图是无状态(每一次请求都会创建一个新的view对象)的,所以不会有线程安全的问题.

2.5.2、View接口图

2.5.3、View的实现类图

2.5.4、View的UML图

视图类型

URL视图资源图

将JSP或其他资源封装成一个视图。被视图解析器InternalResourceViewResolver默认使用。

InternalResourceView的子类。如果JSP中使用了JSTL的国际化标签,就需要使用该视图类。

AbstractExcelView

AbstractPdfView

报表视图

常用的JasperReports报表视图

JasperReportsPdfView

JSON视图

将数据通过Jackson框架的ObjectMapper对象,以JSON方式输出

2.6、其他重要的点

2.6.1、DispatcherServlet.properties


DispatcherServlet.properties内容:

# Default implementation classes for DispatcherServlet's strategy interfaces.# Used as fallback when no matching beans are found in the DispatcherServlet context.# Not meant to be customized by application developers.org.springframework.web.servlet.LocaleResolver=	org.springframework.web.servlet.i18n.AcceptHeaderLocaleResolverorg.springframework.web.servlet.ThemeResolver=	org.springframework.web.servlet.theme.FixedThemeResolverorg.springframework.web.servlet.HandlerMapping=	org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping,\	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping,\	org.springframework.web.servlet.function.support.RouterFunctionMappingorg.springframework.web.servlet.HandlerAdapter=	org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\	org.springframework.web.servlet.function.support.HandlerFunctionAdapterorg.springframework.web.servlet.HandlerExceptionResolver=	org.springframework.web.servlet.mvc.method.annotation.ExceptionHandlerExceptionResolver,\	org.springframework.web.servlet.mvc.annotation.ResponseStatusExceptionResolver,\	org.springframework.web.servlet.mvc.support.DefaultHandlerExceptionResolverorg.springframework.web.servlet.RequestToViewNameTranslator=	org.springframework.web.servlet.view.DefaultRequestToViewNameTranslatororg.springframework.web.servlet.ViewResolver=	org.springframework.web.servlet.view.InternalResourceViewResolverorg.springframework.web.servlet.FlashMapManager=	org.springframework.web.servlet.support.SessionFlashMapManager

转载于:https://www.cnblogs.com/chuchq/p/14489716.html

打赏
0相关评论
相关推荐
热门搜索排行
热门视频
精彩图片
更多
友情链接
声明:本站信息均由用户注册后自行发布,本站不承担任何法律责任。如有侵权请告知立立即做删除处理。
违法不良信息举报邮箱:115904045
头条快讯网 版权所有
中国互联网举报中心