springMVC核心流程分析与视图解析
DispatcherServlet依赖关系图
DispatcherServlet.png
示例代码
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 加注释访问静态资源 /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() );
}
}
核心调用流程
FrameworkServlet#doGet
doGet.png
FrameworkServlet#processRequest
processRequest.png
DispatcherServlet#doService
doService.png
DispatcherServlet#doDispatch
在doDispatch方法中主要有三个重要逻辑
getHandler() 获取处理映射器mappedHandler
getHandlerAdapter() 获取处理适配器HandlerAdapter
ha.handle() 处理适配器调用处理映射器的handler(类)得到ModelAndView视图
获取HandlerExecutionChain
从handlerMappers集合遍历
RequestMappingHandlerMapping
BeanNameUrlHandlerMapping
WebMvcConfigurationSupport/$EmptyHandlerMapping
debug分析请求是test.do
添加了注解@RequestMapping("/test.do")
DispatcherServlet#getHandler
对handlerMappings进行遍历处理查询
AbstractHandlerMapping#getHandler
RMHgetHandler.png
AbstractHandlerMethodMapping#getHandlerInternal
getHandlerInternal.png
得到lookupPath的值
lookupPath.png
AbstractHandlerMethodMapping#lookupHandlerMethod
首先从mappingRegistry集合获取directPathMatches并放到matches集合
lookupHandlerMethod.png
handlerMethod.png
createWithResolvedBean.png
HandlerMethod1.png
executionChain.png
AbstractHandlerMapping#getHandlerExecutionChain
getHandlerExecutionChain.png
returnhandler.png
返回executionChain的handler属性值是HandlerMethod,
interceptors过滤器属性值有
1、ConversionServiceExposingInterceptor
2、ResourceUrlProviderExposingInterceptor
debug分析请求是user.do的获取handler
注解Component("/user.do") BeanNameController类实现了Controller
getHandler-user.png
对handlerMappings集合进行遍历。首先对RequestMapperHandlerMapper调用处理。对lookupHandlerMethod方法调用从mappingRegistry查找,此时这里查找不到
handNoMatch-user.png
然后对handlerMappings的BeanNameUrlHandlerMapper调用处理
AbstractUrlHandlerMapping#lookupHandler
handlerMaplookupHandler.png
会从handlerMap集合获取到/user.do的bean
AbstractUrlHandlerMapping#buildPathExposingHandler
构建HandlerExecutionChain并返回
buildPathExposingHandler.png
BeanNameUHMgethandler.png
并返回HandlerExecutionChain的handler属性值是BeanNameController、
interceptors过滤器属性值
1、AbstractUrlHandlerMapping$PathExposingHandlerInterceptor
2、ConversionServiceExposingInterceptor
3、ResourceUrlProviderExposingInterceptor
debug分析请求是test1.do的获取handler
@Component("/test1.do") HandleController实现了HttpRequestHandler
AbstractUrlHandlerMapping#lookupHandler
gethandlerchain-test1.png
返回的HandlerExecutionChain的handler属性值是HandleController,
interceptors过滤器属性值
1、AbstractUrlHandlerMapping$PathExposingHandlerInterceptor
2、ConversionServiceExposingInterceptor
3、ResourceUrlProviderExposingInterceptor
获取HandlerAdapter
从handlerAdapters集合遍历
RequestMappingHandlerAdapter
HttpRequestHandlerAdapter
SimpleControllerHandlerAdapter
test.do调用
@RequestMapping("/test.do") @Controller注解
DispatcherServlet#getHandlerAdapter
getHandlerAdapter-test.png
AbstractHandlerMethodAdapter#supports
supports.png
RequestMappingHandlerAdapter#supportsInternal
supportsInternal.png
getHandlerAdapter_test.png
返回类型RequestMappingHandlerAdapter
调用user.do
@Component("/user.do") BeanNameController实现了Controller
Controller类全路径org.springframework.web.servlet.mvc.Controller
返回类型SimpleControllerHandlerAdapter
调用test1.do
@Component("/test1.do") HandleController实现了HttpRequestHandler
HttpRequestHandlerAdaptersupports.png
返回类型HttpRequestHandlerAdapter
总结:
本章主要分析得到的HandlerExecutionChain(包括handler和过滤器)和处理适配器HandlerAdapter
HandlerExecutionChain有两种情况
1、加了@RequestMapping注解的
RequestMappingHandlerMapping处理映射器处理,handler返回HandlerMethod(方法)
2、实现了Controller或HttpRequestHandler接口的
BeanNameUrlHandlerMapping处理映射器处理,handler返回实现类的类名
HandlerAdapter有三种情况
1、@RequestMapping,返回类型RequestMappingHandlerAdapter
2、实现了Controller,返回类型SimpleControllerHandlerAdapter
3、实现了HttpRequestHandler,返回类型HttpRequestHandlerAdapter
网友评论