关于SpringMvc的执行流程源码分析大家可以在掘金上找到相关的文章,这里我也就不再重复了。因为之前我也看过,但是其中一个点一直困扰着我,就是SpringMvc在处理请求的时候有一步是从HandleMapping中获取相对应的Handle。这时候问题来了,这个HandleMapping是怎么来的。也就是我们在浏览器输入要访问的路径就能执行对应的方法,这个源码是怎么实现的呢???之前我也试着debug跟着源码走了一遍,发现有一个方法
这个方法是在org.springframework.web.servlet.DispatcherServlet类中的,是不是很开心???想着只要跟着这个方法就可以得到我们想要的答案,最后是得到了我们想要的结果,但是,但是,但是 只是结果,这个过程依然不清楚,也有可能是我个人能力有限,分析不到位。后来我看到一篇文章,说相关的HandleMapping是从AbstractHandleMethodMapping这个类得到的。我就进去看了下
这个类实现了InitializingBean接口,实现了InitializingBean接口的类在初始化的时候都会执行它定义的方法
所以在AbstractHandlerMethodMapping类中肯定也有这个方法的实现
最后会执行initHandleMethod()方法。
这个方法有三步。
第一步:它的作用是获取容器中相关的所有的bean,如下图
第二步:因为我测试的时候只写了个TestController,所以我们这里主要是分析TestController这个类,我直接跳到解析这个类的步骤来了,可以看到beanType这个变量的值,也就是这个类的相关信息
第三步:
这里有个方法 this.isHandler(beanType);我们跟进去看看
看到这个Controller.class和RequestMapping.class是不是很熟悉???没错就是我们在类上使用的@Controller和@RequestMapping注解,也不难想到该方法的主要目的就是判断该类上是否有@Controller或者是@RequestMapping注解。如果有的话那么就会执行 this.detectHandlerMethods(beanName)方法了。
这里就截取了一部分的代码,首先看下第一步有二个值,handleType和userType,看下这个二个值是什么
其实就是TestController这个类的相关信息。重点看下第二步,查看该类的所有方,并且循环解析每个方法看下方法上是否有@RequestMapping注解。 我先放上我写的控制器的代码
接着看下第二步:查看该类的所有方法,并遍历解析,进一步解析是执行this.getMappingForMethod(),这个方法有二个参数,userType前面已经有了,现在看下这个method
其实就是我们在控制器中写的方法,继续跟进去
这里有二个变量 info 和 typeInfo我们先来看下这二个值是什么??
info变量:表示方法上的@RequestMapping注解的value值
typeInfo变量:表示方法上的@RequestMapping注解的value值
知道这二个值了现在也能 明白这个方法的作用,至于具体实现细节这里不讲了,感兴趣的话可以进入源码看下。然后最后返回 info 的值,可以看下
就是拼接好我们访问的路径。 到这里我们已经得到了我们想要的东西了,所以接下来就是将url跟method映射保存起来。我debug进入到了下图这个方法
这里有个put方法,里面传进去二个参数,看下二个参数是什么
就是我们访问的路径和对应要执行的方法。所以在springMvc的执行流程中从HandleMapping中获取对应的Handle,这个HandleMapping就是这样得到的。