• SpringMVC基础源码分析(一)


    实现Controller的三种方式分析

    每种实现的方式对应的HanderAdapter都不同。

    实现Controller接口

    该接口对应的HanderAdapterSimpleControllerHandlerAdapter

    image-20230302193001463

    使用案列:

     public class LeController implements Controller {
    
    	 @Override
    	 public ModelAndView handleRequest(HttpServletRequest request, HttpServletResponse response) throws Exception {
    		 // 创建数据视图类
    		 ModelAndView mv = new ModelAndView();
    		 // 填充数据
    		 mv.addObject("msg","北方情韵");
    		 // 跳转的视图
    		 mv.setViewName("index");
    		 return mv;
    	 }
     }
    

    配置对应的bean信息,这里的name就是访问该Controller的路径。

    <bean class="cn.lele.controller.LeController" name="/le" />
    

    image-20230302192439527

    我们可以通过debug那个执行链就可以知道。

    image-20230302193816106

    实现HttpRequestHandler接口

    该接口对应的HanderAdapterHttpRequestHandlerAdapter

    image-20230302194119786

    使用案例:

     public class YueController implements HttpRequestHandler {
         @Override
         public void handleRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
             request.setAttribute("msg","实现接口HttpRequestHandler");
             request.getRequestDispatcher("/WEB-INF/pages/index.jsp").forward(request,response);
         }
    
     }
    

    配置对应的bean信息,这里的name就是访问该Controller的路径。

    <bean class="cn.lele.controller.YueController" name="/yue" />
    

    image-20230302194358371

    继续查看当前对象的执行链

    image-20230302194510537

    这两种方式大体上是类似的,我们可以区别的看一下,他们是怎么处理的。

    先看实现HttpRequestHandlerAdapter接口的:

    image-20230302194828062

    进入1075行代码:

    image-20230302195104082

    可以发现,这是把当前Controller强转为HttpRequestHander,然后再执行HttpRequestHanderAdapterhandleRequest方法。(实际就是去执行我们Controller里面的方法。)

    image-20230302195206479

    HttpRequestHandler正是我们Contoller类实现的HttpRequestHandler

    image-20230302195708545

    同理,我们去看一下实现Controller接口的类的处理方法。

    image-20230302195830409

    一样,都是先强转为接口类,然后执行对应的方法,也就是我们自己实现的方法:

    image-20230302195925956

    注意:当前的所处位置:

    image-20230302195957002

    使用注解的方式

    待补充

    探究HandlerAdapter的装配规则

    一直都很疑惑:

    image-20230302200218040

    为什么不装配全部都能用,只装配一种,不符合的就不能用了呢?

    未配置HandlerAdapter

    观察DispatcherServlet的初始化方法:

    可以看到有对HandlerAdapter的初始化,点进去加断点。

    image-20230302200635511

    开始Debug:

    image-20230302201006875

    image-20230302201217525

    根据注释,我们可以知道如果此时HandlerAdapters如果为空的话将加载初始化的HandlerAdapters

    image-20230302201509490

    可以看到,在664行加载了四个HandlerAdapter

    image-20230302201646916

    进入此方法继续debug查看:

    注意:DispatcherServlet的初始化方法只执行一次,后面需要重新启动tomcat才能继续进入初始化方法。

    image-20230302201903668

    重启后,继续Debug:

    image-20230302202053167

    往下走,可以看到这里读取到了几个HandlerAdapter

    image-20230302202511819

    很明显872行代码是读取了什么文件

    image-20230302202739434

    重新Debug可以发现这里读取的是org/springframework/web/servlet/DispatcherServlet.properties文件。

    image-20230302202904925

    DispatcherServlet.properties:

    ......
    
    org.springframework.web.servlet.HandlerAdapter=org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter,\
    	org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter,\
    	org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter,\
    	org.springframework.web.servlet.function.support.HandlerFunctionAdapter
    
    
    ......
    

    文件里内容不少,我这里只留下了HandlerAdapter的信息了

    继续往下看怎么处理的:

    下面我感觉应该是利用泛型和反射得到所有的处理器。

    image-20230302204028529

    配置了HandlerAdapter

    如果我们再容器中装配了Adapter:

    image-20230302204619120

    重启tomcat,继续Debug

    image-20230302204651428

    可以看到642行读取到了我们配置的两个HandlerAdapter,并且再645行赋值给了DispatcherServlet的handlerAdapters,此时方法就会结束了。因为下面都不符合条件了。

    image-20230302204909088

    总结:

    如果我们在容器里添加了HandlerAdapter,那么就不会通过读取本地的文件添加默认的四个HandlerAdapter。

    如果没在容器中添加HandlerAdapter,机会读取本地的DispatcherServlet.properties里面的四个HandlerAdapter。


    __EOF__

  • 本文作者: 北方情韵
  • 本文链接: https://www.cnblogs.com/beishanqingyun/p/17173468.html
  • 关于博主: 山回路转不见君,雪上空留马行处。
  • 版权声明: 版权信息:https://www.cnblogs.com/beishanqingyun
  • 声援博主: 如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。
  • 相关阅读:
    msfconsole数据库连接不了的问题【已解决】
    HTTP常见面试题(小林coding版总结)
    LeetCode128. Longest Consecutive Sequence
    DipC 构建基因组 3D 结构(学习笔记)
    c++ stl(标准模板库)
    第五节 C++ 循环结构(算法)
    序列模型之循环神经网络(二)
    win10 上安装 pytorch + cuda
    腾讯云代金券怎么领取(腾讯云代金券在哪领取)
    JAVA高级教程-Java ArrayList(3)
  • 原文地址:https://www.cnblogs.com/beishanqingyun/p/17173468.html