DispatcherServlet源码分析
SpringMVC核心就是DispatcherServlet,所有得请求都会转发到DispatcherServlet,然后再通过DispatcherServlet执行具体得控制层(Handler)返回ModelAndView给客户端视图展示。
// 3. 将我们的DispatcherServlet 注入到 serlvet容器中
ServletRegistration.Dynamic dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(app));
// 4.填写url路径映射
dynamic.addMapping("/");
DispatcherServlet其实就是一个Servlet类,无非就是包装一层,通过url能够映射找到我们得SpringMvc中定义得请求方法。
源代码分析:
DispatcherServlet继承FrameworkServlet继承HttpServlet 面向基本上思想 重写 先走父类 ,在走子类。 得出答案:先看HttpServlet在找到我们最后的子类
protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.processRequest(request, response);
}
关系:DispatcherServlet继承FrameworkServlet继承HttpServlet
流程执行关系:
HttpServlet service方法 判断请求方法的类型 FrameworkServlet doService DispatcherServlet doService
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
...
try {
try {
...
mappedHandler = this.getHandler(processedRequest); //通过url路径地址去查找控制层类方法,如果没有找到的化,直接返回404
....
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = "GET".equals(method);
....
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
....
mappedHandler.applyPostHandle(processedRequest, response, mv);
....
}
private List<HandlerMapping> handlerMappings;
mappedHandler = this.getHandler(processedRequest);
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
}
/**
* 请求方法前置拦截,如果返回true 表示会执行到目标方法(请求方法) 如果返回false的情况下 则不会执行目标方法。
*/
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getParameter("token");
System.out.println(">>>>token<<<<:" + token);
if (StringUtils.isEmpty(token)) {
response.setStatus(500);
response.getWriter().print(" token is null");
return false;
}
// 执行我们的请求方法
return true;
}
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
执行目标方法:
@RequestMapping("/pageIndex")
public String pageIndex() {
System.out.println(">>>pageIndex<<<<");
return "pageIndex";
}
mappedHandler.applyPostHandle(processedRequest, response, mv);
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("<<<postHandle>>>>");
// 请求之后执行。
}
1.执行doDispatch 2.调用getHandler方法获取请求目标的方法 也就是 请求url映射路径对应的控制层具体的方法 handlerMappings的作用查找控制器位置,比如xml和注解方式。 3.调用getHandlerAdapter获取控制层适配器 RequestMappingHandlerAdapter 4.执行拦截器前置方法 preHandle() 如果返回为true的话 5.执行实际请求目标方法 返回modeAndView对象 6.执行拦截器PostHandle()方法 7.设置渲染视图层内容 8.执行拦截器afterCompletion方
SpringMVC控制层容器初始化
protected void onRefresh(ApplicationContext context) {
this.initStrategies(context);
}
当我们servlet容器初始化的时候初始化
this.initHandlerMappings(context);
protected void initStrategies(ApplicationContext context) { initMultipartResolver(context); //初始化上传文件解析器(或者是多部分请求解析器) initLocaleResolver(context);//初始化本地化解析器 initThemeResolver(context);//初始化主题解析器 initHandlerMappings(context);//初始化处理器映射器 initHandlerAdapters(context);//初始化处理器适配器 initHandlerExceptionResolvers(context);//初始化处理器异常解析器 initRequestToViewNameTranslator(context);//初始化请求到视图名翻译器 initViewResolvers(context);//初始化视图解析器 initFlashMapManager(context);//初始化重定向数据管理器 }
本文参考
蚂蚁课堂