DispatcherServlet:
DispatcherServlet#doService(){
//....
doDispatch();//主体流程
//....
}
DispatcherServlet#doDispatch(){
//....
//获取请求中指向的 Handler,返回 HandlerExecutionChain
//HandlerExecutionChain中主要两个属性,【HandlerMapping对当前handler封装对象】+【当前Handler的拦截器数组】
mappedHandler = getHandler(processedRequest);
//....
// 为当前Handler找一个合适的 HandlerAdapter,来执行此Handler
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
//....
}
DispatcherServlet#getHandler() {
//遍历工厂中的 HandlerMapping, HandlerMapping中记录着Handler的访问地址
//但只有认识@RequestMapping注解的HandlerMapping,才真正记录着各个handler的访问地址
for (HandlerMapping hm : this.handlerMappings) {
if (logger.isTraceEnabled()) {
logger.trace(
"Testing handler map ...);
}
// 从HandlerMapping中获取 请求路径对应的Handler
HandlerExecutionChain handler = hm.getHandler(request);
if (handler != null) {//如果当前HandlerMapping可以识别当前请求,则返回
return handler;
}
}
return null;
}
DispatcherServlet#getHandlerAdapter(){
for (HandlerAdapter ha : this.handlerAdapters) {
// ....
if (ha.supports(handler)) {// 遍历多个Adapter,选择一个适合当前Handler的Adapter
return ha;
}
}
}
DispatcherServlet#doDispatch(){
//....
//获取请求中指向的 Handler,返回 HandlerExecutionChain
//HandlerExecutionChain中主要两个属性,【HandlerMapping对当前handler封装对象】+【当前Handler的拦截器数组】
mappedHandler = getHandler(processedRequest);
//....
// 为当前Handler找一个合适的 HandlerAdapter,来执行此Handler
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
//....
//执行拦截器的前置逻辑
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
//紧接着,执行handler,返回一个ModelAndView
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//.....
//执行拦截器的后置逻辑
mappedHandler.applyPostHandle(processedRequest, response, mv);
//.....
//视图渲染,在此方法内部解析完视图渲染后,会调用:
// mappedHandler.triggerAfterCompletion(request, response, null);//拦截器的最终逻辑
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
// processDispatchResult会调用此方法,进行视图渲染
DispatcherServlet#render(ModelAndView mv, HttpServletRequest request, HttpServletResponse response){
// ....
// 解析出一个View对象,其实此View已经在ModelAndView中,在ha执行完handler后就存在了
View view = resolveViewName(...);
// ....
// 调用View的渲染方法,内部将跳转视图,并响应请求
view.render(....);
// 常见的View类型:InternalResourceView用户处理转发跳转,内部使用 request.getRequestDispatcher().forward()
// RedirectView 用于处理重定向,内部使用 response.sendRedirect()
}
第一次访问时,DispatcherServlet启动,启动中会初始化很多,系统组件( HandlerMapping, HandlerAdapter ... ),以及所有Controller。
ComponentScanBeanDefinitionParser 负责解析配置中的 context:component-scan,并扫描Controller,并创建 AnnotationDrivenBeanDefinitionParser 负责解析配置中的 mvc:annotation-driven,并创建对应组件
每种HandlerMapping都有一方法getHandlerInternal(request)为当前请求匹配并返回一个Handler,
但返回类型不一。所谓返回类型不一,是指如果找到匹配的Handler,封装的方法不同,即封装后的对象类型不同。
比如RequestMappingHandlerMapping的返回的是一个HandlerMethod
比如BeanNameUrlHandlerMapping的返回直接是一个Controller对象
细节:
RequestMappingHandlerMapping中的getHandler方法,会调用getHandlerInternal()返回一个 HandlerMethod; 在getHandler方法中再封装进一个HandlerExecutionChain中。
BeanNameUrlHandlerMapping中的getHandler方法,会调用getHandlerInternal()方法,方法中会先找到对应的Controller类,然后直接封装为HandlerExecutionChain,并返回给getHandler方法。
HandlerExecutionChain 中主要封装两类信息:当前handler 、handler的拦截器数组。
一、响应正常格式
二、响应JSON格式(Json响应是靠 HttpMessageConverter,而不是View! )