引言
在分析springMVC框架之前,我们根据我们对整个框架的流程分析,先来手写一个简易版的springMVC框架, 这样我们在看源码的时候会更清晰,毕竟框架源码还是非常庞大的, 如果我们一行一行的看的话, 那就完蛋了,直接陷到里面出不来了。所以本篇 博客我们基于现有的servlet和spring框架来手写模拟一个springMVC框架,在这个框架中我们主要是编写主流程,也就是我们最关系的处理器和适配器等。
一、实现分析
我们在动手之前,首先需要分析一下, springmvc框架到底帮我们做了什么功能,是如何实现的?
1、使用内嵌的tomcat作为servlet容器
2、采用spring IOC容器,将处理器扫描到容器中,并且通过spring的后置处理器 取出处理。(处理器:做业务处理的组件,可以使类后者方法,处理器和url存在映射关系)
注:这里我们需要清楚,@Controller注解是spring提供的,如果我们仅仅添加了这个注解,此时这个类只是一个普通的bean,并不是一个处理器,和@component是一样的。
3、@RequestMapping 是SpringMVC的框架的,所以需要我们自己实现这个注解。
其实核心实现方式,就是我们维护一个Map<url,处理器(Object)>,因为处理器可能是一个类、或者方法等,所以需要object类型。根据前端请求的url找到对应的处理器,然后执行对应的处理逻辑方法。
4、springmvc处理器类型:
1)直接使用@Controller注解搭配@RequestMapping(url)注解来实现处理器,由于我们每个方法 上面都可以使用@RequestMapping注解,所以我们需要通过反射获得对应方法并执行。
2)实现servle接口,获得对应的处理器以后,直接执行service方法
3)实现Controller ,获得对应的处理器以后, 直接执行handleRequest()方法
4)实现HttpRequestHandler,获得对应的处理器以后, 直接执行handleRequest()方法
为什么会有多种实现处理器的方式呢,这是由于历史发展的原因,我们都知道在最开始的时候,我们都是自己实现servlet接口来编程的,所以作为一个成熟的框架当然不能抛弃最原始的功能,所以在springmvc内部实现了多种实现方式。既然有多种处理方式需要我们兼容,所以我们需要判断我们使用哪种控制器以后,才能执行对应的实现逻辑。所以这里为了易于代码的扩展,这里需要适配器模式,给每一种处理都实现一个对应的适配器,具体参考上一篇博客《从SpringMVC看适配器模式》 。
5、适配器:跟映射器一一对应
提供一个统一的接口
判断适配是否成功
执行处理逻辑接口
6、返回参数json,使用@responseBoday注解
7、参数绑定 ,使用@RequestParam注解实现参数绑定
那么这里各位小可爱又会发现一个问题,就是我们平常在使用的时候,很多情况下我们都没有使用这个注解,我们参数也可以正常注入,这是为什么呢?
在JDK1.8之前,这是采用了ASM(字节码技术),通过class文件解析参数,那是因为在jdk1.8之前我们通过反射不能获得参数名称。但是在jdk1.8开始,我们就不在采用asm技术,因为我们可以通过反射获得参数名称了。所以我们在平常使用的时候,如果从性能方面考虑,我们还是需要@RequestParam参数,这样我们更快的完成参数注入。
二、代码实现
以上呢就是我们手写springmvc 容器,需要实现和考虑的问题,下面我们就动手写代码了,先来看代码执行流程
1、基本流程图
原图地址:https://www.processon.com/view/link/5fbcbabd5653bb1d54f57e4c
2、项目结构
3、项目地址:https://github.com/good-jack/self-springmvc
三、小结
大家可以根据流程图,自己在本地起来项目debug几遍流程,就会明白很多,本文没有贴出来代码,是因为代码的每个类都比较简单,但是类比较多,不太好分析,所以需要将代码下载到本地自行调试。在这个项目中我们仅仅实现了springmvc的核心流程及两种实现控制器的方式。当我们理解了这个简易的springmvc框架后,对后面分析真正的springmvc框架源码会有一定的好处。