前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringMVC源码深度解析之DispatcherServlet源码分析

SpringMVC源码深度解析之DispatcherServlet源码分析

作者头像
须臾之余
发布2019-08-05 14:51:16
7840
发布2019-08-05 14:51:16
举报
文章被收录于专栏:须臾之余须臾之余

DispatcherServlet源码分析

SpringMVC核心就是DispatcherServlet,所有得请求都会转发到DispatcherServlet,然后再通过DispatcherServlet执行具体得控制层(Handler)返回ModelAndView给客户端视图展示。

代码语言:javascript
复制
// 3. 将我们的DispatcherServlet 注入到 serlvet容器中
ServletRegistration.Dynamic dynamic = servletContext.addServlet("dispatcher", new DispatcherServlet(app));
// 4.填写url路径映射
dynamic.addMapping("/");

DispatcherServlet其实就是一个Servlet类,无非就是包装一层,通过url能够映射找到我们得SpringMvc中定义得请求方法。

源代码分析:

  1. 类的集成关系

DispatcherServlet继承FrameworkServlet继承HttpServlet 面向基本上思想 重写 先走父类 ,在走子类。 得出答案:先看HttpServlet在找到我们最后的子类

代码语言:javascript
复制
protected final void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    this.processRequest(request, response);
}

DispatcherServlet与Servlet关系

关系:DispatcherServlet继承FrameworkServlet继承HttpServlet

流程执行关系:

HttpServlet service方法 判断请求方法的类型 FrameworkServlet doService DispatcherServlet doService

代码语言:javascript
复制
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);
....
}

SpringMVC源码之定位Handler原理

代码语言:javascript
复制
private List<HandlerMapping> handlerMappings;
代码语言:javascript
复制
mappedHandler = this.getHandler(processedRequest);
代码语言:javascript
复制
HandlerAdapter ha = this.getHandlerAdapter(mappedHandler.getHandler());
代码语言:javascript
复制
if (!mappedHandler.applyPreHandle(processedRequest, response)) {
    return;
}
代码语言:javascript
复制
/**
 * 请求方法前置拦截,如果返回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;
}
代码语言:javascript
复制
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());

执行目标方法:

代码语言:javascript
复制
@RequestMapping("/pageIndex")
public String pageIndex() {
    System.out.println(">>>pageIndex<<<<");
    return "pageIndex";
}
代码语言:javascript
复制
mappedHandler.applyPostHandle(processedRequest, response, mv);
代码语言:javascript
复制
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    System.out.println("<<<postHandle>>>>");
    // 请求之后执行。
}

DispatcherServlet源码流程分析

1.执行doDispatch 2.调用getHandler方法获取请求目标的方法 也就是 请求url映射路径对应的控制层具体的方法 handlerMappings的作用查找控制器位置,比如xml和注解方式。 3.调用getHandlerAdapter获取控制层适配器 RequestMappingHandlerAdapter 4.执行拦截器前置方法 preHandle() 如果返回为true的话 5.执行实际请求目标方法 返回modeAndView对象 6.执行拦截器PostHandle()方法 7.设置渲染视图层内容 8.执行拦截器afterCompletion方

SpringMVC控制层容器初始化

  1. HttpServletBean init ()方法
  2. FrameworkServlet initServletBean方法→ initWebApplicationContext();
  3. DispatcherServlet onRefresh方法→ initStrategies()方法
代码语言:javascript
复制
protected void onRefresh(ApplicationContext context) {
    this.initStrategies(context);
}

当我们servlet容器初始化的时候初始化

代码语言:javascript
复制
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);//初始化重定向数据管理器 }

本文参考

蚂蚁课堂

http://www.mayikt.com/

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • DispatcherServlet与Servlet关系
  • SpringMVC源码之定位Handler原理
  • DispatcherServlet源码流程分析
相关产品与服务
容器服务
腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档