手寫一個迷你版Spring 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就開發完成了。
PS:如果覺得我的分享不錯,歡迎大家隨手點贊、轉發。
Java團長
專注於Java乾貨分享
掃描上方二維碼獲取更多Java乾貨