------------吾亦无他,唯手熟尔,谦卑若愚,好学若饥-------------

先从概念理解,从中央调度器,携带参数request,调度到HandleMapping处理器映射器,处理器映射器返回处理器执行链给中央调度器

我从底层走一遍,印证这个概念:

  1.都说是中央调度器的,所以先找到中央调度器DispatcherServlet

  2.从他里面找到一个方法   ctrl+f 找(doDistch)

    protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
HttpServletRequest processedRequest = request;
HandlerExecutionChain mappedHandler = null;
boolean multipartRequestParsed = false;
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request); try {
try {
ModelAndView err = null;
Exception dispatchException = null; try {
processedRequest = this.checkMultipart(request);
multipartRequestParsed = processedRequest != request;
mappedHandler = this.getHandler(processedRequest);
if(mappedHandler == null || mappedHandler.getHandler() == null) {
this.noHandlerFound(processedRequest, response);
return;
} HandlerAdapter ex = this.getHandlerAdapter(mappedHandler.getHandler());
String method = request.getMethod();
boolean isGet = "GET".equals(method);
if(isGet || "HEAD".equals(method)) {
long lastModified = ex.getLastModified(request, mappedHandler.getHandler());
if(this.logger.isDebugEnabled()) {
this.logger.debug("Last-Modified value for [" + getRequestUri(request) + "] is: " + lastModified);
} if((new ServletWebRequest(request, response)).checkNotModified(lastModified) && isGet) {
return;
}
} if(!mappedHandler.applyPreHandle(processedRequest, response)) {
return;
} err = ex.handle(processedRequest, response, mappedHandler.getHandler());
if(asyncManager.isConcurrentHandlingStarted()) {
return;
} this.applyDefaultViewName(processedRequest, err);
mappedHandler.applyPostHandle(processedRequest, response, err);
} catch (Exception var19) {
dispatchException = var19;
} this.processDispatchResult(processedRequest, response, mappedHandler, err, dispatchException);
} catch (Exception var20) {
this.triggerAfterCompletion(processedRequest, response, mappedHandler, var20);
} catch (Error var21) {
this.triggerAfterCompletionWithError(processedRequest, response, mappedHandler, var21);
} } finally {
if(asyncManager.isConcurrentHandlingStarted()) {
if(mappedHandler != null) {
mappedHandler.applyAfterConcurrentHandlingStarted(processedRequest, response);
}
} else if(multipartRequestParsed) {
this.cleanupMultipart(processedRequest);
} }
}

    这个方法里面很多内容不需要关注,需要关注的的我讲讲

        HttpServletRequest processedRequest = request;
//接收请求
HandlerExecutionChain mappedHandler = null;
//处理器执行链
boolean multipartRequestParsed = false;
//多部分请求,文件上传
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
//异部请求 try {
try { ModelAndView err = null;
//视图解析 try { processedRequest = this.checkMultipart(request);
//检查是否是多部分请求
multipartRequestParsed = processedRequest != request; mappedHandler = this.getHandler(processedRequest);
//这就返回处理器执行链

  3.到这儿,点击getHandler(processedRequest)查看

    protected HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
Iterator var2 = this.handlerMappings.iterator(); HandlerExecutionChain handler;
do {
if(!var2.hasNext()) {
return null;
} HandlerMapping hm = (HandlerMapping)var2.next();
if(this.logger.isTraceEnabled()) {
this.logger.trace("Testing handler map [" + hm + "] in DispatcherServlet with name \'" + this.getServletName() + "\'");
} handler = hm.getHandler(request);
} while(handler == null); return handler;
}

    我把关键代码提炼出来解释一波

        //迭代器,没做泛型,handlerMapping是list集合
Iterator var2 = this.handlerMappings.iterator();
//处理器执行链
HandlerExecutionChain handler;
do {
if(!var2.hasNext()) {
return null;
}
//处理器映射器
HandlerMapping hm = (HandlerMapping)var2.next(); //继续追踪
handler = hm.getHandler(request);
} while(handler == null); return handler;

  4.追踪hm.getHandler(request)方法,发现他是HandlerMapping接口的,(Ctrl+H)找它的实现类AbstractHandlerMapping,ctrl+F找getHandler

    public final HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {
Object handler = this.getHandlerInternal(request);
if(handler == null) {
handler = this.getDefaultHandler();
} if(handler == null) {
return null;
} else {
if(handler instanceof String) {
String executionChain = (String)handler;
handler = this.getApplicationContext().getBean(executionChain);
} HandlerExecutionChain executionChain1 = this.getHandlerExecutionChain(handler, request);
if(CorsUtils.isCorsRequest(request)) {
CorsConfiguration globalConfig = this.corsConfigSource.getCorsConfiguration(request);
CorsConfiguration handlerConfig = this.getCorsConfiguration(handler, request);
CorsConfiguration config = globalConfig != null?globalConfig.combine(handlerConfig):handlerConfig;
executionChain1 = this.getCorsHandlerExecutionChain(request, executionChain1, config);
} return executionChain1;
}
}

    同样,我把关键代码提出来解释一波

    //获取处理器
Object handler = this.getHandlerInternal(request);
//处理器为空就用默认的
if(handler == null) {
handler = this.getDefaultHandler();
}
//默认的也是空就返回null
if(handler == null) {
return null;
} else {
//判断是否是String类型
if(handler instanceof String) {
//这儿就是我们一般用的处理器的从配置文件bean的id
String handlerName = (String)handler; // /hello
//这就是Spring啊
handler = this.getApplicationContext().getBean(handlerName);
}
        //获取处理程序执行链
        HandlerExecutionChain executionChain1 = this.getHandlerExecutionChain(handler, request);
    //返回的时候变成携带处理器的了 
  
    return this.getHandlerExecutionChain(handler, request); }

  5.追踪获取程序执行链,this.getHandlerExecutionChain(handler,request)

    protected HandlerExecutionChain getHandlerExecutionChain(Object handler, HttpServletRequest request) {
//三元表达式,是处理器执行链就强转,不是就获取根据处理器生成一个
HandlerExecutionChain chain = handler instanceof HandlerExecutionChain?(HandlerExecutionChain)handler:new HandlerExecutionChain(handler);
String lookupPath = this.urlPathHelper.getLookupPathForRequest(request);
Iterator var5 = this.adaptedInterceptors.iterator(); while(var5.hasNext()) { //只需要知道这儿添加拦截器即可
HandlerInterceptor interceptor = (HandlerInterceptor)var5.next();
if(interceptor instanceof MappedInterceptor) {
MappedInterceptor mappedInterceptor = (MappedInterceptor)interceptor;
if(mappedInterceptor.matches(lookupPath, this.pathMatcher)) {
chain.addInterceptor(mappedInterceptor.getInterceptor());
}
} else {
chain.addInterceptor(interceptor);
}
} return chain;
}

SSM-SpringMVC-04:SpringMVC深入浅出理解HandleMapping(源码刨析)的更多相关文章

  1. 30s源码刨析系列之函数篇

    前言 由浅入深.逐个击破 30SecondsOfCode 中函数系列所有源码片段,带你领略源码之美. 本系列是对名库 30SecondsOfCode 的深入刨析. 本篇是其中的函数篇,可以在极短的时间 ...

  2. HashMap源码刨析(面试必看)

    目录 1.Hash的计算规则? 2.HashMap是怎么形成环形链表的(即为什么不是线程安全)?(1.7中的问题) 3.JDK1.7和1.8的HashMap不同点? 4.HashMap和HashTab ...

  3. Java 源码刨析 - 线程的状态有哪些?它是如何工作的?

    线程(Thread)是并发编程的基础,也是程序执行的最小单元,它依托进程而存在. 一个进程中可以包含多个线程,多线程可以共享一块内存空间和一组系统资源,因此线程之间的切换更加节省资源.更加轻量化,也因 ...

  4. MapReduce源码刨析

    MapReduce编程刨析: Map map函数是对一些独立元素组成的概念列表(如单词计数中每行数据形成的列表)的每一个元素进行指定的操作(如把每行数据拆分成不同单词,并把每个单词计数为1),用户可以 ...

  5. Flask上下文管理及源码刨析

    基本流程概述 - 与django相比是两种不同的实现方式. - django/tornado是通过传参数形式实现 - 而flask是通过上下文管理, 两种都可以实现,只不实现的方式不一样罢了. - 上 ...

  6. ConcurrentHashMap源码刨析(基于jdk1.7)

    看源码前我们必须先知道一下ConcurrentHashMap的基本结构.ConcurrentHashMap是采用分段锁来进行并发控制的. 其中有一个内部类为Segment类用来表示锁.而Segment ...

  7. Java 源码刨析 - String

    [String 是如何实现的?它有哪些重要的方法?] String 内部实际存储结构为 char 数组,源码如下: public final class String implements java. ...

  8. Java 源码刨析 - HashMap 底层实现原理是什么?JDK8 做了哪些优化?

    [基本结构] 在 JDK 1.7 中 HashMap 是以数组加链表的形式组成的: JDK 1.8 之后新增了红黑树的组成结构,当链表大于 8 并且容量大于 64 时,链表结构会转换成红黑树结构,它的 ...

  9. form 源码刨析

    def clean_name(self) value = self.cleaned_data.get('name') if "金-瓶-梅" not in value: raise ...

随机推荐

  1. droid invalidate和postinvalidate的区别

    Android提供了Invalidate方法实现界面刷新,但是Invalidate不能直接在线程中调用,因为他是违背了单线程模型:Android UI操作并不是线程安全的,并且这些操作必须在UI线程中 ...

  2. Hadoop家族

    现在Hadoop家族产品,已经达到20个了之多. 有必要对自己的知识做一个整理了,把产品和技术都串起来.不仅能加深印象,更可以对以后的技术方向,技术选型做好基础准备. 本文为"Hadoop家 ...

  3. LeetCode之“动态规划”:Unique Binary Search Trees && Unique Binary Search Trees II

    1. Unique Binary Search Trees 题目链接 题目要求: Given n, how many structurally unique BST's (binary search ...

  4. android自定义view实现公章效果

    上次去一个公司面试,面试官问了一个题,怎么用android的自定义view实现一个公章的效果,据说这是华为之前的面试题,我想了下,要是公章的效果,最外层是一个圆,里面是一个五角星,但是这文字怎么画呢, ...

  5. linux信号量与完成量

    信号量:    是用于保护临界区的一种常用方法,它的使用和自旋锁类似.与自旋锁相同,只有得到信号量的进程才能执行 临界区的代码.但是与自旋锁不同的是,当获取不到信号量时,进程不会原地打转而是进入休眠等 ...

  6. 面试之路(10)-BAT面试之java实现单链表的插入和删除

    链表的结构: 链表在空间是不连续的,包括: 数据域(用于存储数据) 指针域(用于存储下一个node的指针) 单项链表的代码实现: 节点类 构造函数 数据域的get,set方法 指针域的get,set方 ...

  7. Struts2数据传输的背后机制:ValueStack(值栈)

    1.     数据传输背后机制:ValueStack(值栈) 在这一切的背后,是因为有了ValueStack(值栈)! ValueStack基础:OGNL 要了解ValueStack,必须先理解OGN ...

  8. jvm性能优化及内存分区

     jvm性能优化及内存分区 2012-09-17 15:51:37 分类: Java Some of the default values for Sun JVMs are listed below. ...

  9. RESTful小拓展

    RESTful 即Resource Representation State Transfer 相对应Resource 资源层,Representation 表现层,State Transfer状态转 ...

  10. 视频客观质量评价工具:MSU Video Quality Measurement Tool【ssim,psnr】

    MSU Video Quality Measurement Tool(msu vqmt)是莫斯科国立大学(Moscow State University)的Graphics and Media Lab ...