1. 程式人生 > >用原生 JDK 擼一個 MVC 框架

用原生 JDK 擼一個 MVC 框架

 

用原生 JDK 擼一個 MVC 框架

 

 

前期準備

我這裡要寫的是一個迷你版的Spring MVC,我將在一個乾淨的web工程開始開發,不引入Spring,完全通過JDK來實現。

我們先來看一眼工程:

工程程式碼結構

第一,在annotation包下,我將提供自定義的註解,為了方便理解,就和Spring MVC保持一致。

第二,為了模擬Spring MVC的方法呼叫鏈,我這裡提供Controller/Service/Dao層進行測試

第三,提供自己的DispatcherServlet完成核心處理邏輯

 

關於自定義註解

JDK提供了幾個元註解,比如:

@Documented : JavaDoc文件

@Target:標誌此註解可以修飾在哪些地方,類,成員變數,方法...

@Retention:Annotation的生命週期,一般情況下,我們自定義註解的話,顯然需要在執行期獲取註解的一些資訊。

看一下我這邊的自定義註解:

模擬Spring MVC的@Controller註解

 

@Qualifier提供依賴注入

 

@RequestMapping提供URL地址處理對映

 

Dao層註解

 

Service層註解

 

編寫核心控制器:DispatcherServlet

在Spring MVC中,DispatcherServlet是核心,下面我們來實現它。首先來說,Spring MVC中的DispatcherServlet說到底,還是HttpServlet的子類,因此我這邊自己的DispatcherSerlvet需要extends HttpServlet。

pom.xml:

提供servlet依賴

看DispatcherServlet的定義:

DispatcherServlet

@WebServlet是什麼?

其實,以前我們定義一個Servlet,需要在web.xml中去配置,不過在Servlet3.0後出現了基於註解的Servlet。

仔細觀察,你會發現,這個DispatcherServlet是自啟動,而且傳入了一個引數。

要知道,在Spring MVC中,要想基於註解,需要在配置中指明掃描的包路徑,就像這個樣子:

<context:component-scan base-package="com.zfz.myspringmvc">

</context:component-scan>

為了方便,我這裡就通過初始化引數直接將需要掃描的基包路徑傳入。

init初始化處理:

init()

其實,在init中,我們主要是完成了什麼呢?

第一,我們應該去掃描基包下的類,得到資訊A

第二,對於@Controller/@Service/@Repository註解而言,我們需要拿到對應的名稱,並初始化它們修飾的類,形成對映關係B

第三,我們還得掃描類中的欄位,如果發現有@Qualifier的話,我們需要完成注入

第四,我們還需要掃描@RequestMapping,完成URL到某一個Controller的某一個方法上的對映關係C

其實,Spring MVC的處理流程,就是類似這樣的!

掃描基包:

掃描基包

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

例項化:

例項化

從這裡你可以看出,我們完成了被註解標註的類的例項化,以及和註解名稱的對映。

依賴注入:

依賴注入

以前,我們總是說Spring IOC,上面不就是在做這個事情麼?

URL對映處理:

URL對映處理

URL,我們需要提取出來,對映到Controller的Method上。

doGet/doPost:

doGet/doPost

在doPost方法中,非常簡單,我們只需要提取出URL,通過URL對映到Method上,然後通過反射的方式進行呼叫即可。

 

Make it run!

Controller層:

UserController

Service層:

UserService

 

UserServiceImpl

Dao層:

UserDao

 

UserDaoImpl

執行結果:

result

OK,到這裡,一個迷你版的Spring MVC就開發完成了,以前,都是用Spring MVC,從沒有想過可以自己開發一個出來,這是我的第一次,我的能量超乎我的想象,哈哈~