经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » Java相关 » Spring » 查看文章
SpringMVC基础源码分析(一)
来源:cnblogs  作者:情韵  时间:2023/3/3 8:52:36  对本文有异议

实现Controller的三种方式分析

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

实现Controller接口

该接口对应的HanderAdapterSimpleControllerHandlerAdapter

image-20230302193001463

使用案列:

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

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

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

image-20230302192439527

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

image-20230302193816106

实现HttpRequestHandler接口

该接口对应的HanderAdapterHttpRequestHandlerAdapter

image-20230302194119786

使用案例:

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

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

  1. <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:

  1. ......
  2. 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
  3. ......

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

继续往下看怎么处理的:

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

image-20230302204028529

配置了HandlerAdapter

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

image-20230302204619120

重启tomcat,继续Debug

image-20230302204651428

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

image-20230302204909088

总结:

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

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

原文链接:https://www.cnblogs.com/beishanqingyun/p/17173468.html

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号