老司机教你用原生JDK 撸一个 MVC 框架!!!
其实 Spring MVC 是一个基于请求驱动的 Web 框架,并且也使用了前端控制器模式来进行设计,再根据请求映射规则分发给相应的页面控制器进行处理,具体工作原理见下图。
在这里,就不详细谈相关的原理和实现细节了,感兴趣的话,可以读一下这方面的书籍。
我在网上看到一篇不错的关于讲述怎么实现一个 MVC 框架的文章,在此,分享给各位读者,也许能帮助到你。
原文内容如下。
我今天主要带大家实现一个迷你版的 Spring MVC ,本项目将在一个干净的 web 工程开发,不引入 Spring,完全通过原生 JDK 来实现。
具体的工程代码结构如下图。
相关代码说明:
- 在 annotation 包下,我将提供自定义的注解,为了方便理解,会与 Spring MVC 保持一致。
- 为了模拟 Spring MVC 的方法调用链,我这里提供 Controller/Service/Dao 层进行测试。
- 提供自定义的 DispatcherServlet 来完成核心逻辑处理。
一、自定义注解
先给各位读者解释一下 JDK 提供了几个元注解:
- @Documented : JavaDoc文档
- @Target:标志此注解可以修饰在哪些地方,类,成员变量,方法...
- @Retention:Annotation的生命周期,一般情况下,我们自定义注解的话,显然需要在运行期获取注解的一些信息。
我这边自定义的注解主要是模拟 Spring MVC ,具体实现如下。
1、@Controller提供控制器
2、@Qualifier提供依赖注入
3、@RequestMapping提供URL地址处理映射
4、Dao层注解
5、Service层注解
二、核心控制器
在 Spring MVC 中,DispatcherServlet 是核心类,下面我的代码主要用来实现它。首先来说,Spring MVC 中的 DispatcherServlet 说到底,还是 HttpServlet 的子类,因此我这边自定义的 DispatcherSerlvet 也需要继承 HttpServlet。
1、pom.xml 加入 servlet 依赖
2、定义 DispatcherServlet
代码中的 @WebServlet 用处是什么呢?其实,以前我们定义一个 Servlet ,需要在 web.xml 中去配置,不过在 Servlet 3.0 后出现了基于注解的 Servlet 。
仔细观察,你会发现,这个 DispatcherServlet 是自启动,而且传入了一个参数。
要知道,在 Spring MVC 中,要想基于注解,需要在配置中指明扫描的包路径,就像这个样子。
为了方便,我这里就通过初始化参数直接将需要扫描的基包路径传入。
a、初始化流程
其实,在 init 中,我们主要是完成了什么呢?
- 我们应该去扫描基包下的类,得到信息 A。
- 对于 @Controller/@Service/@Repository 注解而言,我们需要拿到对应的名称,并初始化它们修饰的类,形成映射关系 B。
- 我们还得扫描类中的字段,如果发现有 @Qualifier 的话,我们需要完成注入。
- 我们还需要扫描 @RequestMapping,完成 URL 到某一个 Controller 的某一个方法上的映射关系 C。
其实,Spring MVC 的处理流程,就是类似这样的!
b、扫描基包
注意,基包是 X.Y.Z 的形式,而 URL 是 X/Y/Z 的形式,需要转换。
c、实例化
从这里你可以看出,我们完成了被注解标注的类的实例化,以及和注解名称的映射。
d、依赖注入
以前,我们总是说Spring IOC,上面不就是在做这个事情么?
e、URL映射处理
我们需要把 URL 提取出来,映射到 Controller 的 Method 上。
f、doGet/doPost
在 doPost 方法中,非常简单,我们只需要提取出 URL,通过 URL 映射到Method 上,然后通过反射的方式进行调用即可。
三、让它跑起来
1、Controller层
2、Service层
3、Dao层
4、运行结果
到这里,一个迷你版的 Spring MVC 就开发完成了。
老司机教你用原生JDK 撸一个 MVC 框架!!!的更多相关文章
- 纯手工撸一个vue框架
前言 vue create 真的很方便,但是很多人欠缺的是手动撸一遍.有些人离开脚手架都不会开发了. Vue最简单的结构 步骤 搭建最基本的结构 打开空文件夹,通过 npm init 命令生成pack ...
- 【Bugly干货分享】老司机教你 “飙” EventBus 3
Bugly 技术干货系列内容主要涉及移动开发方向,是由 Bugly 邀请腾讯内部各位技术大咖,通过日常工作经验的总结以及感悟撰写而成,内容均属原创,转载请标明出处. EventBus对于Android ...
- 老司机教你下载tumblr上视频和图片的正确姿势
本文面向初学者. 很多同学问我:“我非常想学Python编程,但是找不到兴趣点”. 还有的同学呢,找到了很好的兴趣点,但是无从下手,“玄魂老师,我想下载tumblr上的视频, 怎么下载,Python能 ...
- 徒手生撸一个验证框架,API 参数校验不再怕!
你们之中大概率早已练就了代码的拷贝.粘贴,无敌的码农神功,其实做久了业务功能开发,练就这两个无敌神功,那是迟早的事儿.今天先抛一个小问题,来打通你的任督二脉,就是很好奇的问一下:业务功能开发中,输入参 ...
- 靓仔,整合SpringBoot还在百度搜配置吗?老司机教你一招!!!
导读 最近陈某公司有些忙,为了保证文章的高质量可能要两天一更了,在这里陈某先说声不好意思了!!! 昨天有朋友问我SpringBoot如何整合Redis,他说百度谷歌搜索了一遍感觉不太靠谱.我顿时惊呆了 ...
- 老司机教你如何正确地在大陆安装 BlackArch
BlackArch 官方有一个比较完整的安装指南文档,其地址为 https://blackarch.org/blackarch-install.html 正如其第一行所述的那样 This tutori ...
- 线上Bug无法复现怎么办?老司机教你一招,SpringBoot远程调试不用愁!
前言 在部署线上项目时,相信大家都会遇到一个问题,线上的 Bug 但是在本地不会复现,多么无奈. 此时最常用的就是取到前端传递的数据用接口测试工具测试,比如 POSTMAN,复杂不,难受不? 今天陈某 ...
- 老司机教你在windows不用软件隐藏重要文件
每个人电脑里面都有些秘密,但是别人需要使用你的电脑时,有可能会看到,但是我们又不想让别人发现时,我们可以将其隐藏,那么别人就不会看到了.360文件保险柜.腾讯电脑管家等等.使用软件繁琐软件过大还会拖慢 ...
- PHP原生实现简易的MVC框架
目录结构: —|controller —|Home.php —|model —|view —|welcome.php —|index.php 基本原理: 首页 index.php 通过获得地址栏中的路 ...
随机推荐
- 【webpack系列】从零搭建 webpack4+react 脚手架(一)
搭建一个React工程的方式有很多,官方也有自己的脚手架,如果你和我一样,喜欢刨根究底,从零开始自己一行一行代码创建一个React脚手架项目,那你就来对地方了.本教程是针对React新手,以及对web ...
- POSIX-Data Structure
struct sigevent The <signal.h> header shall define the sigeventstructure, which shall include ...
- c++继承学习
继承分类: 虚表继承 class D{ public : d(){ } ~d(){ } private: }; 单重继承 class D{ public : d(){ } ~d(){ } privat ...
- 3步永久性激活pycharm 亲测有效
----------破解后,有效时间会到2099年------------ 1.下载JAR包:此JAR包的目的就是让截获截止时间并骗过pycharm 链接:https://pan.baidu.com/ ...
- VS 2013Ultimate 开发过程中遇到的问题——listbox的隐藏问题,combobox.textchanged的中文问题
最近项目有需求,就是把一个combobox让它可以根据用户输入的汉字就行模糊查询出匹配的下拉框内容,很简单,是吧 但是!!!在开发中真是遇到了不少问题呢. 一.实现流程 1)我的实现思维是这样的,先把 ...
- web应用、HTTP协议及web框架简介
1. web应用 1.1 web应用程序 Web应用程序是一种可以通过Web访问的应用程序,程序的最大好处是用户很容易访问应用程序,用户只需要有浏览器即可,不需要再安装其他软件 B/S模式(浏览器/服 ...
- nginx配置前端代理
#user nobody;worker_processes 1; #error_log logs/error.log;#error_log logs/error.log notice;#error_l ...
- List使用linq的OrderBy方法排序,并按照两个字段排序的写法
SfaMember.GetList(searchInfo, 0, 1000, out Allcount).Where(item => item.bOpen == true).OrderBy(it ...
- java拦截处理System.exit(0)
在使用TestNG做单元测试时,需要测试的代码中出现System.exit(0),导致单元测试还未结束程序就停止了.解决方法如下: public class TestMain { public sta ...
- phantomjs api文档
phantomjs实现了一个无界面的webkit浏览器.虽然没有界面,但dom渲染.js运行.网络访问.canvas/svg绘制等功能都很完备,在页面抓取.页面输出.自动化测试等方面有广泛的应用. 详 ...