作为经典MVC思想的spring实现,它能够帮我们开发灵活的JavaWeb应用。今天我们就来对它动刀,看看它的内部是怎么实现的,我们能不能仿写一份呢?
首先我们通过一张时序图来看一下springMVC的运行流程。
springMVC运行流程
从上面的时序图,我们可看到,一个叫dispatcherServlet的家伙十分繁忙,几乎每一步都有它的参与,他怎么这么忙啊,这就和它的名字有关
dispatcher /dɪs’pætʃə/ n. 发报机,调度员
它就相当于在M-V-C三者之间的邮差,或者说是领导,负责调用各个组件。
我们来假设一下这个场景:
DispatcherServlet是MVC场景里的老大,而且亲力亲为,什么事都要他过目审批,这天他收到了一份用户请求,叫他给出一个网页页面。
他马上给他的副手HandlerMapping,说:“小刘,你看看这个活,谁来干合适?”小刘HandlerMapping一看员工花名册有一个叫小张的Controller能够胜任,小刘就对领导说:“Controller小张能干”。
这时候,领导DispatcherServlet不能直接找到小张,因为小张只负责实现具体业务,而用户的要求太抽象,小张看不懂,需要有个人帮他理一理,第一步该做什么,第二步该做什么。这时候项目经理HandlerAdaper就上线了,领导找到项目经理说:“帮小张理一理,这个活具体该咋做”。
项目经理三下五除二给整完了,之后,领导拿着处理好的任务,将任务交给里小张,我们的小张也很争气呀,也给干完了,而且,他干的工程不仅有业务(Model)还有漂亮的组件(View),不过小张同学的审美不太好,没办法把它们组合到一块。于是,领导DispatcherServlet就吭哧吭哧跑到学美术的viewRsolver身边,让她给渲染一下。viewRsolver画技高超,寥寥几笔渲染出来了一份既有业务资料,也很好看的页面出来。
至此一个项目完成了,DispatcherServlet就拿着成果(JSP等前端页面)展示给用户看,用户心满意足,大方的付了钱,于是,大家都有钱拿…
看完了Rod Johnson的springMVC的MVC 流程,里面组件分工明确,各司其职,能够完成很多复杂的业务,但是我们刚开始上手,肯定不能上来就整这么多,因此今天我们搭一个简单版的,只有领导(DispatcherServlet)和各类业务员等。业务员,还是只负责具体业务,其他的活全让领导干。
我们的流程:
在我们的流程中 DispatcherServlet领导 = 前端控制器 + 映射处理器
好了明确了我们要搭的任务,现在建哥来手把手教学,开搞!
<!– 引入servlet jar –><dependency><groupId>javax.servlet</groupId><artifactId>javax.servlet-api</artifactId><version>3.1.0</version><scope>provided</scope></dependency><!– 引入反射jar包–><dependency><groupId>org.reflections</groupId><artifactId>reflections</artifactId><version>0.9.11</version></dependency>
在resource目录下编写配置文件:applicationContext.properties,内容为:指定扫描路径package,我们在这里指定controller所在的包
package=com.cloudwise.controller
骨架用的还是2.0版本,我们在这里更新为4.0的。
并且注册我们的领导MyDispatcherServlet并为其指定配置文件所在位置contextConfigLocation,我们的领导凡事亲力亲为,在这里让他拦截所有请求。
注解在这里的作用就相当于给类/方法加上一个小尾巴,我们通过不同的尾巴辨识不同的Controller和Method
我们定义两个注解
好了上面的就是一些准备性的工作,如果说把仿写springMVC看成是组成一个团队的话,上面的工作相当于给团队找工作场地,下面就是对人物的刻画了,首先有请我们的领导MyDispatcherServlet
编写前端控制器(一个Servlet),并重写init和service方法
MyDispatcherServlet
整个过程围绕两个重写的方法而展开,其中init()是重点。
MyDispatcherServlet要做的事,用一句话来说:看前端的访问地址,然后调用匹配的处理器(Controller)的对应方法(method)
要完成这些,我们需要通过注解,为Controller和method绑定上一定的字符串,然后通过分析前端传过来的Url中的字符串,找到两者相同的,以此完成匹配。反射在此过程中发挥了巨大作用,不论是找到类头上的注解,还是找到注解中的值等诸多动作都需要反射。
Init
Service 注:在此处Handler = controller + method
创建一个dispatcherServlet继承httpservlet 并重写两个方法
接下来就是填充两个方法了,首先是init()方法
它大概可以分为4步
那我们开始吧,写加载配置文件的代码
首先,我们在这里选用properties文件的形式进行配置,因此,需要有一个properties对象
那么至此,我们的第一步加载配置文件部分的代码就写完啦
另外三步采用同样的思路
定义所需属性
在init()中调用
(Handler = controller + method)
/*** 存储所有方法的Map<url:method>*/private Map<String,Method> methodMap = new HashMap<>();/*** 存储所有Controller的Map*/private Map<String,Object> controllerMap = new HashMap<>();
具体实现方法
好了至此,我们的领导MyDispatcherServlet 的初始化部分就写完了,现在他已经对自己的团队成员:众多业务员们(Controller)已经了如指掌了(有同学可能会问:陈老师,你还没定义Controller呢!这个先不急)下面,我们就重写他的service()方法,让他能够到外面接活
至此,MyDispatcherServlet的所有代码都已经完成了,他也能够成为一个合格的领导了。
上面部分代码写的较为分散,文末放上MyDispatcherServlet的完整代码供同学们参考
1.为本项目配置tomcat
2.运行
3.1浏览器地址栏输入对应网址
控制台成功打印日志信息
3.2浏览器地址栏输入无效网址,页面返回404
至此,今天的手写springMVC就全部完成了。
当然本项目还有很多待提升的地方,诸如不能返回json数据,controller不能有参数,等等。但是我们不可能一朝一夕建成罗马,应该一步一个脚印,通过这个项目掌握springMVC的运行流程,为以后更难的项目打下点基础。
本文由知识库于2021-09-13发表在龙哥云资源网,如有疑问,请联系我们。本文链接:https://www.longgeyun.com/knowledge/3313.html
上一篇cisco路由器设置步骤图解(新手配置交换机详细教程)
下一篇ps白色背景怎么设置(ps抠图教程入门图解)
高校最常见的食物中毒有哪些
急性肠胃炎与食物中毒怎么分辨
莫代尔面料和纯棉面料哪个好内裤 哪个儿童可以穿
为什么说开速腾的都不是一般人 速腾开出去有面子吗
活珠子和毛蛋的区别在哪里 哪个好吃
家里放石头的八大禁忌有哪些 家中石头最佳摆放位置
怎么判断自己帅还是丑男 男生怎样越长越帅
单身女生红绳戴左手还是右手 女生红绳戴哪里合适
Pr2020零基础快速入门
文字转语音App最新版3.0
APP下载页源码-带后台