天天看點

自定義簡陋版SpringMVC

這幾天在家寫了一個簡陋版的SpringMVC,先把代碼貼出來,有興趣的同學可以看一下。

這裡用了線程池來處理多個socket連接配接。

接着我們需要自定義一個Request和Response兩個類來處理請求和響應資訊。

Request這裡存了請求頭資訊、請求參數資訊、請求類型、請求URI等。Request的代碼如下:

Response這裡隻處理了傳回簡單字元串和傳回靜态資源檔案,Response的代碼如下:

這裡我們模仿Servlet,也自定義一個Servlet接口。代碼如下:

它的一個實作類如下,在這個類中我們根據URI找到對應的請求處理類,并調用響應的請求方法。

接着我們模仿Spring寫幾個注解:

模仿Spring的Autowire注解

模仿Spring的Component注解:

模仿Controller注解:

模仿RequestMapping注解:

這裡根據請求找到對應的處理類和處理方法的思路是:定義一個Map,key是請求URI,value是自定義的一個類。這個自定義的類(RequestMappingInfo)包含這幾個資訊:Class資訊、Method類、對象、請求參數和方法參數。java類在編譯為class的時候有release和debug模式之分,在指令行中直接使用javac進行編譯的時候,預設的時候release模式,使用release模式會改變形參中的參數名。而IDE都是使用debug模式進行編譯的。ant編譯的時候,需要在ant的配置檔案中指定debug="true"。

如果要修改javac編譯類檔案的方式的話,需要指定-g參數。即:javac -g 類檔案。通常我們都是用IDE進行項目開發的,是以我們的java類在編譯成class的時候參數是不會變的,而SpringMVC在處理參數這個地方用到了ASM技術,來擷取參數的資訊,并且是在第一次處理請求的時候,來擷取參數資訊并放到緩存中,以後都從緩存中擷取參數資訊。RequestMappingInfo代碼如下:

接着我們定義一個類友善IOC:

接着就是我們比較重要的類了ApplicationContext,我們會在這裡類中,簡單模仿Spring IOC的過程,掃描固定包下固定注解的類。在這裡遇到了一個問題,一開始在加載類的時候自己寫了一個類加載器,但是一個類加載器在他的生命周期中隻會加載這個類一次,是以會出現多次加載同一個類的情況。後來别人推薦了一個小工具類:Reflections,這個問題才比較完美的解決,Reflections是一個很不錯的工具類,可以掃描Classpath下面任意的類,并且讓反射更容易。如下:掃描帶某個注解的類,擷取含有方法名為某個字元串的類等等。github位址在這兒:https://github.com/ronmamo/reflections,裡面有很多例子。自定義的ApplicationContext的代碼如下:

下面我們寫個Controller類來測試一下:

我們在浏覽器中輸入:http://localhost:8005/custom/myFirstPage.do來看一下結果:

控制台輸出如下:

自定義簡陋版SpringMVC

傳回結果如下:

自定義簡陋版SpringMVC

和我們程式寫的結果一樣。

接着我們寫一個稍微複雜一點的,定義一個javaBean、DAO類、Service類。

UserScope

DAO

Service:

從上面的代碼中我們可以看到在DAO的實作類上我們用了CustomComponent注解,在Service的實作類上我們用了CustomService的注解。在我們的那個Controller中我們又用了CustomAutowire這個注解。下面我們通路一下看看效果,我們在浏覽器中輸入:http://localhost:8005/custom/inserUser.do?userName=hangssewe&passWord=2ewewe

自定義簡陋版SpringMVC

浏覽器輸出為:

自定義簡陋版SpringMVC

我們在Controller中的inserUser這個方法中設定了兩個Cookie,我們來看一下Cookie有沒有設定成功:

自定義簡陋版SpringMVC

結果和我們預想的是一樣的。

接着我們寫一個靜态資源的處理類:

通路一下看看效果如何:

自定義簡陋版SpringMVC

這裡遇到的一個問題是在Chrome浏覽器中通路的時候會報錯,在IE浏覽器中通路則正常顯示,還沒搞清楚為什麼會出現這樣的問題。