1.springmvc的核心组件
以下是 Spring MVC 的核心组件:
1.DispatcherServlet(前端控制器):
定义:DispatcherServlet 是 Spring MVC 的前端控制器(Front
Controller),它作为应用程序的入口点,负责处理所有的请求和响应。 作用:DispatcherServlet 根据请求的 URL
和配置的处理器映射,将请求分派给适当的处理器(Controller)进行处理,并获取处理结果。
2.HandlerMapping(处理器映射):
HandlerMapping 将请求映射到相应的处理器(Controller)进行处理。 Spring MVC 提供了多种
HandlerMapping 的实现,包括注解驱动的 RequestMappingHandlerMapping、基于接口的
BeanNameUrlHandlerMapping 等。 Controller(控制器:
3.Controller 是处理请求并返回响应的组件。
在 Spring MVC 中,可以使用多种方式定义 Controller,包括使用注解标记的控制器类、实现特定接口的控制器类等。
4.HandlerAdapter(处理器适配器):
HandlerAdapter 负责将请求分派给相应的 Controller 进行处理。 HandlerAdapter 根据不同的
Controller 类型调用相应的方法,并处理请求的参数绑定、数据转换、验证等操作。
5.ViewResolver(视图解析器):
ViewResolver 将逻辑视图名称解析为实际的视图对象。 Spring MVC 提供了多种 ViewResolver 的实现,包括
InternalResourceViewResolver(用于解析 JSP 视图)、ThymeleafViewResolver(用于解析
Thymeleaf 模板视图)等
6.View(视图):
View 负责渲染模型数据并生成最终的响应内容。 不同的视图技术有不同的实现,如 JSP 视图、Thymeleaf
视图、FreeMarker 视图等
。
2.springmvc的执行流程
- 用户向服务器发送请求,请求被springmvc前端控制器dispatcherservlet捕获
- dispatcherservlet对请求去url进行解析,得到请求次元标识符url,判断url对应的映射:
不存在:
1.再判断配置了mvc:default-servlet-handler
2.如果没有配置,则控制台包映射查找不到,客户端展示404错误
3.如果有配置:测访问目标资源(一般为静态资源),找不到客户端也会报404的错误
存在:
根据url,调用handlereMapping获得该handler配置的所有相关对象(包括handler对象以及handler对象对应的拦截器),最后以handlerExecutionChain执行链对象的形式返回
2. dispatcherservlet根据获得的handler选择一个合适的handleradapter- 如果成功获得handleradapter,此时将开始执行拦截器的prehandler方法(正向)
- 提取request中的模型数据,填充handler入参,开始执行handler方法,处理请求,再填充handler的入参过程中,根据你的配置,spring将帮你做一些额外的工作
(1).httpmessagerconveter:将请求消息转换为一个对象,将对象转换为指定的相应消息
(2).数据转换:将请求消息进行数据转换,如string转换为integer等
(3).数据格式化:将请求消息进行数据格式化,将字符串转化为格式化数字或者格式化日期
(4).数据验证:检验数据的有效性(长度,格式),将验证结果储存到bindingresult或者error中
- handler执行完成后,向dispatcherservlet返回一个modelandview对象- 此时将开始执行拦截器的posthandle方法逆向
- 根据返回的modelandview(此时会判断是否存在异常,如果存在异常则执行handlerresolver进行异常处理)选择一个适合的viewresolver进行视图解析,根据model和view,来渲染视图
- 渲染视图完毕执行拦截器的aftercompletion方法
- 将渲染结果返回给客户端
代码展示:
用户向服务器发送请求,
调用DispatcherServlet中继承下来的service方法,对请求方式进行判断
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpMethod httpMethod = HttpMethod.resolve(request.getMethod());
if (httpMethod != HttpMethod.PATCH && httpMethod != null) {
super.service(request, response);
} else {
this.processRequest(request, response);
}
}
然后调用this.processRequest(request, response);在这个方法中紧接着调用了this.doService(request, response);再调 this.doDispatch(request, response);
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
try {
try {
ModelAndView mv = null;
Exception dispatchException = null;
try {
processedRequest = this.checkMultipart(request);
multipartRequestParsed = processedRequest != request;
/*根据handlerMapping获取到执行连对象,执行链对象中有三个属性
private final Object handler;执行器对象
private List<HandlerInterceptor> interceptorList;配置的拦截器
private int interceptorIndex;用于记录拦截器的执行个数,起始为-1*/
mappedHandler = this.getHandler(processedRequest);
if (mappedHandler == null) {
this.noHandlerFound(processedRequest, response);
return;
}
// 根据this.getHandlerAdapter(mappedHandler.getHandler())获取到合适的执行器适配器对象
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
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;
}
}
//执行连接器的的PreHandle方法,执行顺序按照配置的先后顺序,其中默认的是第一个执行的
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
//执行handler方法实现controller中的方法,并返回一个modelAndView对象
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
if (asyncManager.isConcurrentHandlingStarted()) {
return;
}
this.applyDefaultViewName(processedRequest, mv);
//执行拦截器中的PostHandle方法,执行顺序按照配置的反序进行
mappedHandler.applyPostHandle(processedRequest, response, mv);
} catch (Exception var20) {
dispatchException = var20;
} catch (Throwable var21) {
dispatchException = new NestedServletException("Handler dispatch failed", var21);
}
this.processDispatchResult(processedRequest, response, mappedHandler, mv, (Exception)dispatchException);
} catch (Exception var22) {
//执行拦截器中的AfterCompletion(方法,执行顺序按照配置的反序进行
this.triggerAfterCompletion(processedRequest, response, mappedHandler, var22);
} catch (Throwable var23) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, new NestedServletException("Handler processing failed", var23));
}
} finally {
if (asyncManager.isConcurrentHandlingStarted()) {
if (mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
} else if (multipartRequestParsed) {
this.cleanupMultipart(processedRequest);
}
}
}