用原生 JDK 撸一个 MVC 框架

其实我之前写关于 Struts 安全《 Struts,你为何死不悔改!》的时候,就讲过 MVC 的原理了,其实 Spring MVC 就是在此原理上产生的,它是一个基于请求驱动的 Web 框架,并且也使用了前端控制器模式来进行设计,再根据请求映射规则分发给相应的页面控制器进行处理,具体工作原理见下图。

用原生 JDK 撸一个 MVC 框架

在这里,就不详细谈相关的原理和实现细节了,感兴趣的话,可以读一下这方面的书籍。

我在网上看到一篇不错的关于讲述怎么实现一个 MVC 框架的文章,在此,分享给各位读者,也许能帮助到你。

原文内容如下。

我今天主要带大家实现一个迷你版的 Spring MVC ,本项目将在一个干净的 web 工程开发,不引入 Spring,完全通过原生 JDK 来实现。

具体的工程代码结构如下图。


用原生 JDK 撸一个 MVC 框架

相关代码说明:

  1. 在 annotation 包下,我将提供自定义的注解,为了方便理解,会与 Spring MVC 保持一致。

  2. 为了模拟 Spring MVC 的方法调用链,我这里提供 Controller/Service/Dao 层进行测试。

  3. 提供自定义的 DispatcherServlet 来完成核心逻辑处理。

一、自定义注解

先给各位读者解释一下 JDK 提供了几个元注解:

  • @Documented : JavaDoc文档

  • @Target:标志此注解可以修饰在哪些地方,类,成员变量,方法...

  • @Retention:Annotation的生命周期,一般情况下,我们自定义注解的话,显然需要在运行期获取注解的一些信息。

我这边自定义的注解主要是模拟 Spring MVC ,具体实现如下。

1、@Controller提供控制器

用原生 JDK 撸一个 MVC 框架

2、@Qualifier提供依赖注入

用原生 JDK 撸一个 MVC 框架

3、@RequestMapping提供URL地址处理映射

用原生 JDK 撸一个 MVC 框架

4、Dao层注解


用原生 JDK 撸一个 MVC 框架
5、Service层注解
用原生 JDK 撸一个 MVC 框架
二、核心控制器

在 Spring MVC 中,DispatcherServlet 是核心类,下面我的代码主要用来实现它。首先来说,Spring MVC 中的 DispatcherServlet 说到底,还是 HttpServlet 的子类,因此我这边自定义的 DispatcherSerlvet 也需要继承 HttpServlet。

1、pom.xml 加入 servlet 依赖


用原生 JDK 撸一个 MVC 框架
2、定义 DispatcherServlet
用原生 JDK 撸一个 MVC 框架

代码中的 @WebServlet 用处是什么呢?其实,以前我们定义一个 Servlet ,需要在 web.xml 中去配置,不过在 Servlet 3.0 后出现了基于注解的 Servlet 。

仔细观察,你会发现,这个 DispatcherServlet 是自启动,而且传入了一个参数。

要知道,在 Spring MVC 中,要想基于注解,需要在配置中指明扫描的包路径,就像这个样子。

为了方便,我这里就通过初始化参数直接将需要扫描的基包路径传入。

a、初始化流程

用原生 JDK 撸一个 MVC 框架
其实,在 init 中,我们主要是完成了什么呢?
  • 我们应该去扫描基包下的类,得到信息 A。

  • 对于 @Controller/@Service/@Repository 注解而言,我们需要拿到对应的名称,并初始化它们修饰的类,形成映射关系 B。

  • 我们还得扫描类中的字段,如果发现有 @Qualifier 的话,我们需要完成注入。

  • 我们还需要扫描 @RequestMapping,完成 URL 到某一个 Controller 的某一个方法上的映射关系 C。

其实,Spring MVC 的处理流程,就是类似这样的!

b、扫描基包


用原生 JDK 撸一个 MVC 框架

注意,基包是 X.Y.Z 的形式,而 URL 是 X/Y/Z 的形式,需要转换。

c、实例化


用原生 JDK 撸一个 MVC 框架
从这里你可以看出,我们完成了被注解标注的类的实例化,以及和注解名称的映射。

d、依赖注入

用原生 JDK 撸一个 MVC 框架以前,我们总是说Spring IOC,上面不就是在做这个事情么?

e、URL映射处理

用原生 JDK 撸一个 MVC 框架我们需要把 URL 提取出来,映射到 Controller 的 Method 上。

f、doGet/doPost


用原生 JDK 撸一个 MVC 框架在 doPost 方法中,非常简单,我们只需要提取出 URL,通过 URL 映射到Method 上,然后通过反射的方式进行调用即可。

三、让它跑起来

1、Controller层


用原生 JDK 撸一个 MVC 框架

2、Service层


用原生 JDK 撸一个 MVC 框架
用原生 JDK 撸一个 MVC 框架


3、Dao层


用原生 JDK 撸一个 MVC 框架
用原生 JDK 撸一个 MVC 框架


4、运行结果


用原生 JDK 撸一个 MVC 框架

到这里,一个迷你版的 Spring MVC 就开发完成了。


原文发布时间为: 2018-10-21
本文作者:Java面试那些事儿
本文来自云栖社区合作伙伴“Java面试那些事儿”,了解相关信息可以关注“Java面试那些事儿”。

上一篇:超百位计算机系学生报名,蚂蚁金服联合浙江大学举办CodeLab科技创新营


下一篇:[Leetcode 33]有序旋转数组找值Search in Rotated Sorted Array