Spring MVC

一、3W

  1. Why:原生Servlet操作麻烦》提升开发效率
  2. What:表述层和控制层各细分领域需要解决的问题全方位覆盖,提供全面解决方案
  3. How:统一的DispatcherServlet

二、初始化过程

1、加载WebApplicationContext(spring容器):ContextLoaderListener》initWebApplicationContext
2、DispatcherServlet初始化过程(SpringMVC容器):
在这里插入图片描述

initWebApplicationContext事项:

  • 初始化WebApplicationContext>创建WebApplicationContext>DispatcherServlet初始化策略

三、执行流程

1、Spring MVC整体流程在这里插入图片描述

2、DispatcherServlet调用组件处理源码分析
…》processRequest()>doService()>doDispatch()>processDispatchResult()

/*
    mappedHandler:调用链
    包含handler、interceptorList、interceptorIndex
    handler:浏览器发送的请求所匹配的控制器方法
    interceptorList:处理控制器方法的所有拦截器集合
    interceptorIndex:拦截器索引,控制拦截器afterCompletion()的执行
*/
mappedHandler = getHandler(processedRequest);

// 通过控制器方法创建相应的处理器适配器,调用所对应的控制器方法
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

// 调用拦截器的preHandle()
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
    return;
}

// 由处理器适配器调用具体的控制器方法,最终获得ModelAndView对象
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

applyDefaultViewName(processedRequest, mv);

// 调用拦截器的postHandle()
mappedHandler.applyPostHandle(processedRequest, response, mv);

// 后续处理:处理模型数据和渲染视图
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);

// 处理模型数据和渲染视图
render(mv, request, response);

// 调用拦截器的afterCompletion()
mappedHandler.triggerAfterCompletion(request, response, null);        	

在这里插入图片描述

四、解析、绑定/转换/验证

  1. doService:943, DispatcherServlet在向请求域中存一些数据。
  2. doDispatch:1040, DispatcherServlet (org.springframework.web.servlet)根据请求地址从处理器映射器中拿到要执行的handler,再拿到处理器适配器(HandlerAdapter)去执行Handler。
  3. handle:87, AbstractHandlerMethodAdapter (org.springframework.web.servlet.mvc.method)
  4. handleInternal:792, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)具体的处理类
  5. invokeHandlerMethod:878, RequestMappingHandlerAdapter (org.springframework.web.servlet.mvc.method.annotation)大部分都是赋值
  6. returnValue = invokeAndHandle:105, ServletInvocableHandlerMethod 通过反射的方式调用指定的方法去执行此次请求
    1). invokeForRequest:134, InvocableHandlerMethod
  • Object[] args = getMethodArgumentValues:167, InvocableHandlerMethod 获取此次请求执行所需的参数
for(int i = 0; i < parameters.length; ++i) {循环	根据parameters数组中每一个参数的信息拿到参数值放到Object数组中。
	args[i] = this.resolvers.resolveArgument:121, HandlerMethodArgumentResolverComposite (org.springframework.web.method.support)
		HandlerMethodArgumentResolver resolver = this.getArgumentResolver(parameter);获取具体的解析器:存在多种(RequestResponseBody*、RequestParam*、ServletRequest*、RequestHeader*、PathVariable*等)
		return resolver.resolveArgument:131, RequestResponseBodyMethodProcessor (org.springframework.web.servlet.mvc.method.annotation)具体的解析类去执行。
			readWithMessageConverters:158, RequestResponseBodyMethodProcessor (org.springframework.web.servlet.mvc.method.annotation)						
				readWithMessageConverters:230, AbstractMessageConverterMethodArgumentResolver (org.springframework.web.servlet.mvc.method.annotation)
					for (HttpMessageConverter<?> converter : this.messageConverters) {循环尝试多种转换器(根据contentType)
						转换器:MappingJackson2*、ByteArray*、String*、MappingJackson2Xml*
  • return this.doInvoke(args); 拿到此次请求的参数后去执行具体的控制层中方法。

    2). returnValueHandlers.handleReturnValue(returnValue 处理结果,与处理请求类似,循环尝试多种转换器

		handleReturnValue:81, HandlerMethodReturnValueHandlerComposite 
			handleReturnValue:174, RequestResponseBodyMethodProcessor 
				writeWithMessageConverters:224, AbstractMessageConverterMethodProcessor 

HttpMessageConverter接口有只有5个方法,根据MediaType处理;接收到请求时判断是否能读(canRead),能读则读(read);返回结果时判断是否能写(canWrite),能写则写(write)。

四、其它

  1. HandlerAdapter、HandlerMapping
  2. 拦截器 :配置》注解
  3. 异常处理 :配置》注解
  4. 配置类替换*.xml的方式

五、获取请求参数几种方式

3.1 通过ServletAPI获取请求参数
3.2 通过控制器方法的形参获取请求参数

参数名要求一致

3.3 @RequestParam、@RequestHeader、@CookieValue 、@PathVariable注解

@RequestHeader注解 和 @CookieValue注解 的属性和用法跟@RequestParam相同,不同的是
@RequestHeader注解是将请求头信息和控制器方法的形参创建映射关系
@CookieValue注解是将cookie数据和控制器方法的形参创建映射关系

3.4 通过POJO获取请求参数
3.5 @RequestBody 注解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值