SpringMVC基础源码分析(一) - 情韵
source link: https://www.cnblogs.com/beishanqingyun/p/17173468.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
实现Controller的三种方式分析
每种实现的方式对应的HanderAdapter都不同。
实现Controller接口
该接口对应的HanderAdapter
为SimpleControllerHandlerAdapter
。
使用案列:
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" />
我们可以通过debug那个执行链就可以知道。
实现HttpRequestHandler接口
该接口对应的HanderAdapter
为HttpRequestHandlerAdapter
。
使用案例:
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" />
继续查看当前对象的执行链
:
这两种方式大体上是类似的,我们可以区别的看一下,他们是怎么处理的。
先看实现HttpRequestHandlerAdapter
接口的:
进入1075行代码:
可以发现,这是把当前Controller强转为HttpRequestHander
,然后再执行HttpRequestHanderAdapter
的handleRequest
方法。(实际就是去执行我们Controller里面的方法。)
而HttpRequestHandler
正是我们Contoller类实现的HttpRequestHandler
。
同理,我们去看一下实现Controller
接口的类的处理方法。
一样,都是先强转为接口类,然后执行对应的方法,也就是我们自己实现的方法:
注意:当前的所处位置:
使用注解的方式
探究HandlerAdapter的装配规则
一直都很疑惑:
为什么不装配全部都能用,只装配一种,不符合的就不能用了呢?
未配置HandlerAdapter
观察DispatcherServlet的初始化方法:
可以看到有对HandlerAdapter的初始化,点进去加断点。
开始Debug:
根据注释,我们可以知道如果此时HandlerAdapters如果为空的话将加载初始化的HandlerAdapters
可以看到,在664行加载了四个HandlerAdapter
进入此方法继续debug查看:
注意:
DispatcherServlet
的初始化方法只执行一次,后面需要重新启动tomcat才能继续进入初始化方法。
重启后,继续Debug:
往下走,可以看到这里读取到了几个HandlerAdapter
很明显872行代码
是读取了什么文件
重新Debug可以发现这里读取的是org/springframework/web/servlet/DispatcherServlet.properties
文件。
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的信息了
继续往下看怎么处理的:
下面我感觉应该是利用泛型和反射得到所有的处理器。
配置了HandlerAdapter
如果我们再容器中装配了Adapter:
重启tomcat,继续Debug
可以看到642行读取到了我们配置的两个HandlerAdapter,并且再645行赋值给了DispatcherServlet的handlerAdapters
,此时方法就会结束了。因为下面都不符合条件了。
总结:
如果我们在容器里添加了HandlerAdapter,那么就不会通过读取本地的文件添加默认的四个HandlerAdapter。
如果没在容器中添加HandlerAdapter,机会读取本地的DispatcherServlet.properties里面的四个HandlerAdapter。
__EOF__
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK