简述SprintMVC过程
SprintMVC
SpringMVC是一个对servlet进行大量封装的Spring框架的组件,,基于MCV架构模式,用于表现层的开发。
SpringMVC中包含两个容器,Spring作为父容器,SpringMVC作为子容器。
简略过程
通过映射器找到url对应的控制器,但控制器需要实现处理器的接口,且有多种方式实现,因此需要适配器确定是哪个处理器接口,确定好处理器接口后,可以直接调用控制器重写的方法,完成控制器的逻辑并返回ModelAndView给DispatcherServlet,DispatcherServlet通过视图解析器将逻辑视图名匹配到视图,然后通过浏览器渲染展示。
= Spring容器和SpringMVC容器启动
= 遍历处理器映射器,获取请求对应的处理器执行链(封装的handler和interceptor)
= 遍历处理器适配器,获取支持处理器的处理器适配器
= 调用适配器的handle方法,执行控制器实现处理器接口的重写方法,完成控制器的逻辑,返回ModelAndView
= 根据ModelAndView获取到Model和View对象,合并Model的数据和request属性,然后对view进行渲染,响应到浏览器
public class DispatcherServlet extends FrameworkServlet {
private List<HandlerMapping> handlerMappings;
}
1、MVC容器启动
// 创建、加载Spring配置并刷新Spring容器(Root WebApplicationContext)
ContextLoader#initWebApplicationContext()
// 初始化Servlet相关的bean,创建并刷新SpringMVC容器
FrameworkServlet#initServletBean()
.......
2、初始化DispatcherServlet策略接口
【通过发布事件及事件监听处理器来】初始化MVC九大组件(DispatcherServlet策略接口) ,DispatcherServlet.properties文件中默认配置了DispatcherServlet策略接口的实现类。
// 初始化HandlerMapping、HandlerAdapter和ViewResolver
protected void initStrategies(ApplicationContext context){
// 开启detectAll,获取HandlerMapping类型的bean,赋值给handlerMappings列表
// 关闭detectAll,获取beanName为handlerMapping且类型为HandlerMapping的bean, 赋值给handlerMappings列表
// handlerMappings==null,获取默认策略的实现类, 赋值给handlerMappings列表
initHandlerMappings(context);
// 开启detectAll,获取HandlerAdapter类型的bean,赋值给handlerAdapters列表
// 关闭detectAll,获取beanName为handlerAdapter且类型为HandlerAdapter的bean, 赋值给handlerAdapters列表
// handlerAdapters==null,获取默认策略的实现类, 赋值给handlerAdapters列表
initHandlerAdapters(context);
// 同上面类似
initViewResolvers(context);
}
3、请求处理流程
SpringMVC遵循Servlet的生命周期,Servlet生命周期主要有三个重要的方法init()、service()、destory()。
FrameworkServlet#service() # 接收请求
FrameworkServlet#processRequest() # 处理LocaleContext和ServletRequestAttributes
FrameworkServlet#doService() #
DispatcherServlet#doService() # 设置HttpServletRequest属性
DispatcherServlet#doDispatch() # 请求分发【处理实际的请求,分发给handler】
Process the actual dispatching to the handler.
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 从HandlerMapping中获取当前请求对应的HandlerExecutionChain对象 (handler and any interceptors)
HandlerExecutionChain mappedHandler = getHandler(processedRequest);
// 从HandlerExecutionChain拿到handler对象,再获取handler对应的HandlerAdapter对象
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Apply preHandle methods of registered interceptors.
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
// Actually invoke the handler,返回ModelAndView
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
// view==null,根据request设置默认的view名
applyDefaultViewName(processedRequest, mv);
// Apply postHandle methods of registered interceptors.
mappedHandler.applyPostHandle(processedRequest, response, mv);
//处理分发结果
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
getHandler方法中返回请求的HandlerExecutionChain对象
public interface HandlerMapping {
// Return a handler and any interceptors for this request.
// The choice may be made on request URL, session state,
// or any factor the implementing class chooses.
@Nullable
HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception;
}
控制器
- ParameterizableViewController:请求路径url直接到视图
- AbstractCommandController:
SpringMVC中重写处理器(handle)的三种方式:
- 实现HttpRequestHandler接口,重写handleRequest方法
public class TestController implements HttpRequestHandler {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
return null;
}
}
- 实现Controller接口,重写handleRequest方法
public class TestController implements Controller {
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
return null;
}
}
- @Controller注解
@Controller
public class TestController {
}
映射器
HandlerMapping的三个实现类
DispatcherServlet#doDispatch()
-->DispatcherServlet#getHandler() // 遍历handlerMappings,返回request的HandlerExecutionChain对象(handler and any interceptors)
-->AbstractHandlerMapping#getHandler() // 获取请求的handler,返回获得的HandlerExecutionChain对象,处理跨域问题
-->AbstractHandlerMethodMapping#getHandlerInternal() // 查找请求的最优匹配handler method,返回HandlerMethod对象
-->AbstractHandlerMethodMapping#lookupHandlerMethod() // 返回请求对应的HandlerMethod对象(Controller的beanName、Class对象、method...)
-->HandlerMethod#createWithResolvedBean() // 获取Controller的beanName,返回 封装handler(Controller)的HandlerMethod对象
-->AbstractHandlerMapping#getHandlerExecutionChain() // 创建处理器执行链对象,封装handler处理器和添加匹配请求的interceptor拦截器
RequestMappingHandlerMapping#afterPropertiesSet() // RequestMappingInfo.BuilderConfiguration 属性赋值
-->AbstractHandlerMethodMapping#initHandlerMethods() // Scan beans in the ApplicationContext
-->AbstractHandlerMethodMapping#processCandidateBean() // 处理被Controller、RequestMapping注解修饰bean
-->AbstractHandlerMethodMapping#detectHandlerMethods() // 获取访问路径与控制器方法的映射关系
-->AbstractHandlerMethodMapping#registerHandlerMethod() // Register a handler method and its unique mapping
适配器
适配器根据supports()判断控制器实现了哪个处理器接口,最后调用控制器重写实现处理器接口的方法,完成控制器的逻辑,返回ModelAndView
DispatcherServlet#doDispatch()
-->DispatcherServlet#getHandlerAdapter() // 遍历handlerAdapters,返回supports(handler)的HandlerAdapter
// 调用HandlerAdapter的handle()方法,完成控制器的逻辑
-->RequestMappingHandlerAdapter#handleInternal()
-->RequestMappingHandlerAdapter#invokeHandlerMethod() // Invoke the RequestMapping handler method preparing a ModelAndView...
-->RequestMappingHandlerAdapter#createInvocableHandlerMethod() // 参数绑定、处理请求以及返回值处理
......
视图解析器
通过ModelAndView对象解析出View对象并且获取Model对象,将Model对象的数据和request的属性合并为mergedModel, 然后设置mergedModel到request属性中;确定request dispatcher的路径,获取请求分发器(RequestDispatcher)进行转发
DispatcherServlet#doDispatch()
-->DispatcherServlet#processDispatchResult() // 处理异常的ModelAndView对象,渲染页面,触发Interceptor的afterCompletion
-->DispatcherServlet#render() // 获取View对象,设置响应状态码,页面渲染,
-->DispatcherServlet#resolveViewName() // 遍历viewResolvers,根据视图名称,解析出View对象
......