springMVC核心流程分析與視圖解析
DispatcherServlet依賴關(guān)系圖
示例代碼
package com.mvc;
public class MyWebApplicationInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext servletContext) {
//初始化spring 容器 以注解的方式
AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
ac.register( AppConfig.class);
DispatcherServlet servlet = new DispatcherServlet(ac);
ServletRegistration.Dynamic registration = servletContext.addServlet("app", servlet);
registration.setLoadOnStartup(1);
// registration.setInitParameter("contextConfigLocation","spring mvc.xml 的地址");
registration.addMapping("*.do");
}
}
package com.mvc;
@Controller
public class TestController {
@RequestMapping("/test.do")
@ResponseBody //user 對象 Map
public Object test(String name, HttpServletRequest request, HttpServletResponse response ){
request.getParameter("name");
Map hashMap = new HashMap();
hashMap.put("key","value");
return hashMap;
}
@RequestMapping("/model.do")
//@ResponseBody 加注釋訪問靜態(tài)資源 /app/index.html
public String model(HttpServletRequest request,HttpServletResponse response){
// /app/index.html
return "index";
}
}
package com.mvc;
@Component("/test1.do")
public class HandleController implements HttpRequestHandler {
@Override
public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.println("111");
}
}
package com.mvc;
import org.springframework.web.servlet.mvc.Controller;
@Component("/user.do")
public class BeanNameController implements Controller{
@Override
public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
System.out.println("beanName");
return null;
}
}
package com;
@Configuration
@ComponentScan("com.mvc")
@EnableWebMvc
public class AppConfig implements WebMvcConfigurer{
@Override
public void configureViewResolvers(ViewResolverRegistry registry) {
registry.jsp( "/app/",".html" );
}
@Override
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
converters.add( new FastJsonHttpMessageConverter() );
}
}
核心調(diào)用流程
FrameworkServlet#doGet
FrameworkServlet#processRequest
DispatcherServlet#doService
DispatcherServlet#doDispatch
在doDispatch方法中主要有三個重要邏輯
getHandler() 獲取處理映射器mappedHandler
getHandlerAdapter() 獲取處理適配器HandlerAdapter
ha.handle() 處理適配器調(diào)用處理映射器的handler(類)得到ModelAndView視圖
獲取HandlerExecutionChain
從handlerMappers集合遍歷
RequestMappingHandlerMapping
BeanNameUrlHandlerMapping
WebMvcConfigurationSupport/$EmptyHandlerMapping
debug分析請求是test.do
添加了注解@RequestMapping("/test.do")
DispatcherServlet#getHandler
對handlerMappings進行遍歷處理查詢
AbstractHandlerMapping#getHandler
AbstractHandlerMethodMapping#getHandlerInternal
得到lookupPath的值
AbstractHandlerMethodMapping#lookupHandlerMethod
首先從mappingRegistry集合獲取directPathMatches并放到matches集合
AbstractHandlerMapping#getHandlerExecutionChain
返回executionChain的handler屬性值是HandlerMethod,
interceptors過濾器屬性值有
1茉贡、ConversionServiceExposingInterceptor
2惕它、ResourceUrlProviderExposingInterceptor
debug分析請求是user.do的獲取handler
注解Component("/user.do") BeanNameController類實現(xiàn)了Controller
對handlerMappings集合進行遍歷。首先對RequestMapperHandlerMapper調(diào)用處理聊训。對lookupHandlerMethod方法調(diào)用從mappingRegistry查找窒篱,此時這里查找不到
然后對handlerMappings的BeanNameUrlHandlerMapper調(diào)用處理
AbstractUrlHandlerMapping#lookupHandler
會從handlerMap集合獲取到/user.do的bean
AbstractUrlHandlerMapping#buildPathExposingHandler
構(gòu)建HandlerExecutionChain并返回
并返回HandlerExecutionChain的handler屬性值是BeanNameController咆霜、
interceptors過濾器屬性值
1、AbstractUrlHandlerMapping$PathExposingHandlerInterceptor
2忆矛、ConversionServiceExposingInterceptor
3察蹲、ResourceUrlProviderExposingInterceptor
debug分析請求是test1.do的獲取handler
@Component("/test1.do") HandleController實現(xiàn)了HttpRequestHandler
AbstractUrlHandlerMapping#lookupHandler
返回的HandlerExecutionChain的handler屬性值是HandleController请垛,
interceptors過濾器屬性值
1、AbstractUrlHandlerMapping$PathExposingHandlerInterceptor
2洽议、ConversionServiceExposingInterceptor
3宗收、ResourceUrlProviderExposingInterceptor
獲取HandlerAdapter
從handlerAdapters集合遍歷
RequestMappingHandlerAdapter
HttpRequestHandlerAdapter
SimpleControllerHandlerAdapter
test.do調(diào)用
@RequestMapping("/test.do") @Controller注解
DispatcherServlet#getHandlerAdapter
AbstractHandlerMethodAdapter#supports
RequestMappingHandlerAdapter#supportsInternal
返回類型RequestMappingHandlerAdapter
調(diào)用user.do
@Component("/user.do") BeanNameController實現(xiàn)了Controller
Controller類全路徑org.springframework.web.servlet.mvc.Controller
返回類型SimpleControllerHandlerAdapter
調(diào)用test1.do
@Component("/test1.do") HandleController實現(xiàn)了HttpRequestHandler
返回類型HttpRequestHandlerAdapter
總結(jié):
本章主要分析得到的HandlerExecutionChain(包括handler和過濾器)和處理適配器HandlerAdapter
HandlerExecutionChain有兩種情況
1、加了@RequestMapping注解的
RequestMappingHandlerMapping處理映射器處理亚兄,handler返回HandlerMethod(方法)
2混稽、實現(xiàn)了Controller或HttpRequestHandler接口的
BeanNameUrlHandlerMapping處理映射器處理,handler返回實現(xiàn)類的類名
HandlerAdapter有三種情況
1审胚、@RequestMapping匈勋,返回類型RequestMappingHandlerAdapter
2、實現(xiàn)了Controller膳叨,返回類型SimpleControllerHandlerAdapter
3洽洁、實現(xiàn)了HttpRequestHandler,返回類型HttpRequestHandlerAdapter