spring

springMVC核心流程

2019-11-24  本文已影响0人  loveFXX

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进行遍历处理查询

getHandler.png
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

loolupHandler-test1.png
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注解

getHandlerAdapter.png
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

SimpleControllerHAsupports.png
返回类型SimpleControllerHandlerAdapter

调用test1.do

@Component("/test1.do") HandleController实现了HttpRequestHandler

getHandler-test1.png
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

上一篇下一篇

猜你喜欢

热点阅读