• SpringMVC源码解析-doDispatch方法


    断点入口

    容器启动后,我们根据URL访问接口,我们的DispatcherServlet都做了什么操作呢?

    我们可以在DispatcherServlet类中的doDispatch方法中打断点来详细查看;

    为什么直接在doDispatch方法中打断点?

    由图可知DispatcherServlet继承自HttpServlet抽象类,我们的get/post请求分别会请求其doGetdoPost方法;

    DispatcherServlet的父类FrameworkServlet中对doGetdoPost方法进行了重写,都会执行this.processRequest(request, response);

    1. protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    2. this.processRequest(request, response);
    3. }
    4. protected final void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    5. this.processRequest(request, response);
    6. }

    processRequest方法会执行方法:this.doService(request, response);而FrameworkServlet中的doService是抽象的,具体实现方法是在DispatcherServlet中;

        protected abstract void doService(HttpServletRequest request, HttpServletResponse response) throws Exception;
    

    DispatcherServlet中的doService则执行了关键方法:this.doDispatch(request, response)

    所以我们执行把断点打在此方法处,看DispatcherServlet具体都做了什么操作。

    doDispatch方法

    前言:除了新建一个类使用@Controller注解,还有什么方法能够新建一个Controller呢?

    实现Controller接口或者是实现HttpRequestHandler接口也是可以做到的,重写其handleRequest方法,不要忘记使用Component("/URI")注解哦。

    执行doDispatch,直接看主要方法 :getHandler

    Spring是通过HandlerMapping对象来查找Handler(就是Controller)的,通过不同的HandlerMapping实现来查找不同方式创建的Controller;

    通过断点可以看到默认会有两个HandlerMapping的实现:RequestMappingHandlerMapping和BeanNameUrlHandlerMapping;

     

    所有加了@Controller的Controller对象会放在RequestMappingHandlerMapping的父类AbstractHandlerMethodMapping的内部类MappingRegistry的一个Map属性中去,

    而所以以BeanName形式定义的Controller对象会放在BeanNameUrlHandlerMapping的父类AbstractUrlHandlerMapping的Map属性中去。

    1. class MappingRegistry {
    2. private final MultiValueMap<String, T> pathLookup = new LinkedMultiValueMap();
    3. }
    1. public abstract class AbstractUrlHandlerMapping extends AbstractHandlerMapping implements MatchableHandlerMapping {
    2. private final Map<String, Object> handlerMap = new LinkedHashMap();
    3. }

    通过HandlerMapping .getHandler(request)方法返回一个封装了Handler的HandlerExecutionChain对象并返回;

    接着执行getHandlerAdapter方法,通过Handler获取其对应的HandlerAdapter适配器;

    HandlerAdapter也同样有多个实现,依据不同的Handler,通过supports方法判断该Handler是哪个类的实现,来返回不同的适配器实现;

    1. protected HandlerAdapter getHandlerAdapter(Object handler) throws ServletException {
    2. if (this.handlerAdapters != null) {
    3. Iterator var2 = this.handlerAdapters.iterator();
    4. while(var2.hasNext()) {
    5. HandlerAdapter adapter = (HandlerAdapter)var2.next();
    6. if (adapter.supports(handler)) {
    7. return adapter;
    8. }
    9. }
    10. }
    11. throw new ServletException("No adapter for handler [" + handler + "]: The DispatcherServlet configuration needs to include a HandlerAdapter that supports this handler");
    12. }

    接着会执行HandlerAdapter.handle方法,将根据适配器调用Controller的具体业务,不同的适配器处理对应的handle处理方式各不相同;

    最后返回ModelAndView对象。

    流程概览图


     

     

     

  • 相关阅读:
    类和对象
    献给转java的c#和java程序员的数据库orm框架
    Dijkstra --- 数组实现(在此基础上可直接改为STL的Queue实现)
    模型微调(fine-tuning)
    如何优雅的比较两个对象是否相等
    Linux(八)——解压缩
    Datawhale机器学习学习总结22-11-27
    java设计模式---建造者模式
    java计算机毕业设计springboot+vue企业的信息管理系统
    【趣学算法】Day4 分治算法——二分搜索
  • 原文地址:https://blog.csdn.net/Firstlucky77/article/details/125447588