作用:Spring MVC 的入口函数。接收请求,响应结果,相当于转发器,中央处理器。有了 DispatcherServlet 减少了其它组件之间的耦合度。用户请求到达前端控制器,它就相当于 MVC 模式中的 C,DispatcherServlet 是整个流程控制的中心,由它调用其它组件处理用户的请求,DispatcherServlet 的存在降低了组件之间的耦合性。
- 处理器映射器 HandlerMapping
作用:根据请求的 url 查找 Handler。HandlerMapping 负责根据用户请求找到 Handler 即处理器(Controller),SpringMVC 提供了不同的映射器实现不同的映射方式,例如:配置文件方式,实现接口方式,注解方式等。
- 处理器适配器 HandlerAdapter
作用:按照特定规则(HandlerAdapter 要求的规则)去执行 Handler。通过 HandlerAdapter 对处理器进行执行,这是适配器模式的应用,通过扩展适配器可以对更多类型的处理器进行执行。
- 处理器 Handler
注意:编写 Handler 时按照 HandlerAdapter 的要求去做,这样适配器才可以去正确执行 Handler。Handler 是继 DispatcherServlet 前端控制器的后端控制器,在 DispatcherServlet 的控制下 Handler 对具体的用户请求进行处理。由于 Handler 涉及到具体的用户业务请求,所以一般情况需要工程师根据业务需求开发 Handler。
- 视图解析器 View resolver
作用:进行视图解析,根据逻辑视图名解析成真正的视图(View )。View Resolver 负责将处理结果生成 View 视图,View Resolver 首先根据逻辑视图名解析成物理视图名即具体的页面地址,再生成 View 视图对象,最后对 View 进行渲染将处理结果通过页面展示给用户。SpringMVC 框架提供了很多的 View 视图类型,包括:jstlView、freemarkerView、pdfView 等。一般情况下需要通过页面标签或页面模版技术将模型数据通过页面展示给用户,需要由工程师根据业务需求开发具体的页面。
- 视图 View
View 是一个接口,实现类支持不同的 View 类型(jsp、freemarker…)。
注意:处理器 Handler(也就是我们平常说的 Controller 控制器)以及视图层 View 都是需要我们自己手动开发的。其他的一些组件比如:前端控制器 DispatcherServlet、处理器映射器 HandlerMapping、处理器适配器 HandlerAdapter 等等都是框架提供给我们的,不需要自己手动开发。
-
DispathcerServlet的继承结构图:
-
HttpServlet
-
|__HttpServletBean
-
|__FrameworkServlet
-
|__DispatcherServlet
DispathcerServlet中的doDispatch方法
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 当前HTTP请求
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通常有三种方法:
// (1) @Controller (2)实现HttpRequestHandler接口,并覆写handleRequest方法,将controller类通过@Component标注为Bean (3)通过xml配置.
mappedHandler = getHandler(processedRequest);
// 如果没有找到对应的Handler,直接返回404
if (mappedHandler == null) {
noHandlerFound(processedRequest, response);
return;
}
// 查找当前请求处理器对应的适配器 HandlerAdapter
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// 获得HTTP请求方法
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;
}
}
// 处理请求之前,执行拦截器的preHandler方法,获取到配置的所有拦截器,循环遍历,依次执行
// 如果拦截器执行过程中返回了false,则直接返回,不会再执行目标方法
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// Actually invoke the handler.
// 执行SpringMVC中真实对应的业务方法
// HandlerAdapter的实现子类有: AbstractHandlerMethodAdapter、HttpRequestHandlerAdapter
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
// 查找视图路径. prefix + uri + suffix
applyDefaultViewName(processedRequest, mv);
// 处理请求之后执行拦截器方法. postHandle方法
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);
}
// 将处理完成之后的结果进行页面视图渲染。比如:跳转到Jsp页面.
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
catch (Exception ex) {
// 页面渲染过程中,如果出现异常,则会直接执行afterCompletion方法
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);
}
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新
如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Java)
Java高频面试专题合集解析:
当然在这还有更多整理总结的Java进阶学习笔记和面试题未展示,其中囊括了Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构资料和完整的Java架构学习进阶导图!
更多Java架构进阶资料展示
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
资料展示**
[外链图片转存中…(img-oTX3g8Yl-1712869037456)]
[外链图片转存中…(img-s8GZgSxG-1712869037457)]
[外链图片转存中…(img-Ch0Dh8x7-1712869037457)]
一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
[外链图片转存中…(img-kwNL512w-1712869037457)]