老司机教你用原生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 通过获得地址栏中的路 ...
随机推荐
- n2n windows 编译安装文件
n2n安装 n2n原理编译版下载,可直接使用:windows下vpn客户端 n2n_v2_linux_x64 n2n_v2_Win32TAP网卡驱动 #linux环境编译yum install -y ...
- macOS10.13.2配置TensorFlow
安装Python python3是通过Homebrew安装的,默认安装的是3.7.0版本,但TensorFlow目前只能在3.4,3.5,3.6上安装,因此首先需要安装3.6版本的python. 首先 ...
- 机器A定时发文件给机器B-FTP实现
机器A发文件的虚拟机 机器B收文件的虚拟机 机器A: 确认linux安装了ftp包,能启用ftp命令 定时器使用的是crontab 定时器设置步骤: 1.进入root用户 2.service cron ...
- 强制.net 程序以32位模式运行
You can modify the PE header of the executable (using the "Corflags.exe" .NET Framework SD ...
- python之socketserver实现并发
python之socketserver实现并发 服务端 import socketserver #socketserver模块是用来实现并发 # 我们自己的类里一定要继承socketserver.Ba ...
- 2019工作计划idea
2019.2.24 工作需求: 汇总 2008-2018年 销售订单数据; 分类历史订单数据, 并可能采取方法进行预测(预测只是一种行为不代表结果) 目前已知条件: 订单生产周期; 45天(标准天数) ...
- Vray
VRay是由chaosgroup和asgvis公司出品,中国由曼恒公司负责推广的一款高质量渲染软件.
- hive动态分区和混合分区
各位看官,今天我们来讨论下再Hive中的动态分区和混合分区方面的一些知识点以及相关的一些问题. 前面我们已经讲过管理表和外部表的一般分区的一些知识点,对于需要对表创建很多的分区,那么用户就需要些很多的 ...
- vue 图片预览插件
https://github.com/daidaitu1314/vue2-preview //cnpm cnpm install vue2-preview -save //引入 import VueP ...
- Vue知识点总结
1.属性名已$开头的都是内部提供的属性 2.为什么使用事件修饰符的原因:methods 只有纯粹的数据逻辑,而不是去处理 DOM 事件细节 3.v-if 如果值为false,元素在页面中不存在:值为t ...