今天被公司派到別的公司談項目,剛去就先被面試了一波(原來是把我外包到別的公司做項目了 -。-),面試時候問了我一個問題,很簡單,就是問我java開發web項目為什麼要用spring,springmvc?

好吧,當時我人直接懵逼了,什麼鬼問我這個!!不就是可以省去很多功夫讓我們踏踏實實寫業務代碼嘛?

當時就隨便回答了一些,回到公司仔細想想,發現還有挺多可以想,可以講的。我想起了之前項目的控制層從struts2轉到springmvc,我就在想為什麼我們現在做javaweb開發,要用struts2或者springMVC這樣的框架,而不是使用servlet加jsp這樣的技術呢?特別是現在我們web的前端頁面都是使用freemaker這樣的模板語言進行開發,拋棄了jsp,這樣的選擇又會給我們javaweb開發帶來什麼樣的好處,延著這個問題的思路,我又發現新的疑問,為什麼現在很多java企業級開發都會去選擇spring框架,spring框架給我們開發的應用帶來了什麼?這麼一想我人更加糊塗了,很難找帶讓自己完全信服的答案。

最終我發現,這些我認為「用」的很熟悉技術,其實還有很多讓我陌生不解的地方,這些陌生和不解的地方也正是我是否能更高層次使用它們的關鍵。

首先,軟體裏有很多優秀的框架,有一種類型的框架,它的特點是建立在一個現有技術的基礎上,提供和現有技術一樣業務功能的技術框架,這個新的技術框架比原技術更加易用,更加健壯同時功能更加強大,例如常用的jQuery,以及上面提到的spring和springMVC(其實是一個啦),深究這些框架都是很複雜的,但是它們的優點其實只有一個:就是讓使用者只關心核心業務的開發,框架幫你屏蔽原有技術跟業務開發無關的各類技術問題。像jQuery,springMVC這類框架之所以優秀,就是它們在這點上做的太好了,以至於很多使用它的程序員都已經不清楚原有技術的真實面目,因此我們要將springmvc理解的更好,使用的更加熟練和深入,這裡我們就要跳出springmvc的技術,到springmvc技術的源頭servlet,仔細研究下servlet的特點,只有這樣我們才能把springmvc框架學的更好(所以才那麼多人看springmvc的源碼學習吧)。

先講講servlet吧,servlet的作用就是是接收瀏覽器傳給服務端的請求(request),並將服務端處理完的響應(response)返回給用戶的瀏覽器,瀏覽器和服務端之間通過http協議進行溝通,其過程是瀏覽器根據用戶的選擇將相關信息按http協議報文的規範組裝請求的http報文,報文通過網路傳輸到指定的伺服器,伺服器通過特定的web容器接收這個報文信息,例如:tomcat,jetty,jboss這樣的web容器,web容器會將http報文解析出來,如果是用戶請求,最終解析出來的報文信息會用一個request對象存儲起來,服務端使用這個request做完相應的處理後,服務端程序將結果信息封裝到response對象裏,然後將response對象交給web容器,web容器則把這個response對象轉變為http協議的報文,並將報文回傳給瀏覽器,瀏覽器最後解析這個響應報文,將最終結果展示給用戶。

而Web容器創造了servlet介面,servlet介面就是開發人員自己實現業務邏輯的地方,程序員開發servlet就好比做填空題,而填空題的語境或者說上下文提示就是由request和response對象,但是javaEE規範裏的servlet介面很簡單,就三個方法init,service和destory,但是這個介面太籠統了,所以規範裏還提供了一個HttpServlet類,這個類根據http請求類型提供了doGet,doPost等方法,servlet介面最大的特點就是根據http協議的特點進行定義,因此做servlet開發時候如果使用者對http協議特點不是特別熟悉,都會碰到或多或少令人迷惑的問題,特別是碰到一些複雜特殊的請求時候:例如文件上傳,返回特殊的文件格式到瀏覽器,這時候使用servlet開發就不是很方便了,servlet開發還有個問題可能大家常常被忽視,就是請求的數據的類型轉化,http協議傳輸都是文本形式,到了web容器解析後也是文本類型,如果碰到貨幣,數字,日期這樣的類型需要我們根據實際情況進行轉化,如果頁面傳送的信息非常多,我們就不得不做大量類型轉化,這種工作沒有什麼技術含量,是個體力活而且很容易導致程序錯誤。

servlet另一個作用就是構造response對象,讓頁面獲得正確的響應,其實現代的瀏覽器是一個多媒體工具,文字,圖片,視屏等等東西都可以在瀏覽器裏顯示,資源的不同就會導致http響應報文的差別,如果我們使用servlet開發就要根據資源的不同在java程序裏用硬編碼的形式處理,這樣的程序很難復用,而且如果程序員對某種資源的處理理解不到位,就會導致問題的出現。

而在SpringMVC 中,控制器Controller 負責處理由DispatcherServlet 分發的請求,它把用戶請求的數據經過業務處理層處理之後封裝成一個Model ,然後再把該Model 返回給對應的View 進行展示。在SpringMVC 中提供了一個非常簡便的定義Controller 的方法,你無需繼承特定的類或實現特定的介面,只需使用@Controller 標記一個類是Controller ,然後使用@RequestMapping 和@RequestParam 等一些註解用以定義URL 請求和Controller 方法之間的映射,這樣的Controller 就能被外界訪問到。此外Controller 不會直接依賴於HttpServletRequest 和HttpServletResponse 等HttpServlet 對象,它們可以通過Controller 的方法參數靈活的獲取到。

servlet裏還有兩個重要的技術:監聽器和過濾器,對於監聽器在web開發裏使用的場景比較少,都是一些十分特別的情況才會使用,大部分web開發裏可以忽略它的使用,我們用的最多的監聽器可能就是對ServletContext創建和銷毀的監聽器,ServletContext是整個web應用的全局對象,它和Web應用的生命週期綁定在一起,因此使用這個監聽器對Web應用的全局信息進行初始化和銷毀操作,例如spring容器的初始化操作。而過濾器方面,使用SpringMVC攔截器和Struts2一樣,Spring MVC也可以使用攔截器對請求進行攔截處理,用戶可以自定義攔截器來實現特定的功能,自定義的攔截器必須實現HandlerInterceptor介面。

下面再談談spring

spring技術可以說是java企業開發裏最重要的技術,不過真的理解spring的作用和意義還真是一件麻煩的事情,很多人對spring理解其實都是停留在使用階段(例如:聲明式事務很好用等等),當今的spring技術生態環境裏可謂是蔚為壯觀,spring已經包羅萬象,它的內容之多完全不亞於它的本源java語言了,而spring這麼大的框都是建立在ioc和aop技術之上,只有深入理解了這兩個技術我們才能明白為什麼spring這個框能裝的下那麼多東西了。

首先是ioc,ioc技術第一個解釋叫做控制反轉,它還有個解釋就是依賴注入,這兩個名字很難從字面理解,但是當你理解它的原理後就會發現它們的描述是何等準確。Ioc技術的本質就是構建對象的技術換句話說就是將一個類實例化成對象的技術,在java裏實例化類通過new關鍵字進行的,每次new一個類都會產生一個新的實例對象,這麼做視乎很浪費,有時這種浪費還挺危險,因為在程序開發時候我們常常只需要某個類永遠只能產生一個的實例對象這個時候就得使用單例模式,此外在設計模式裏還可以通過工廠方式產生對象,使用過spring的人看到上面的文字就知道了,spring裏bean的定義就和上面的內容一一對應,scope屬性single產生單例對象,prototype產生新對象,bean還可以通過工廠方式產生對象,可以說spring的bean就是製造對象的工具。面向對象編程裏對象相當於顯示生活中的一個實體,例如我們有個對象作用是完成打獵的操作,那麼打獵這個對象內部包含兩個輔助對象:人和槍,只有人和槍賦予了打獵這個對象,那麼打獵對象才能完成打獵的操作,但是構建一個人和槍的對象並不是看起來那麼簡單,這裡以槍為例,要創造一把槍我們需要金屬,需要機牀,需要子彈,而機牀和子彈又是兩個新對象,這些對象一個個相互嵌套相互關聯,大夥試想下如果我們在java代碼裏構建一個槍的對象那是何其的複雜,假如我們要構造的不是簡單的槍對象而是更加複雜的航空母艦,那麼構造這個對象的成本之高是讓人難以想像的,怎麼來消除這種對象相互嵌套相互依賴的關係了?spring提供了一種方式,這種方式就是spring提供一個容器,我們在xml文件裏定義各個對象的依賴關係,由容器完成對象的構建,當我們java代碼裏需要使用某個實例的時候就可以從容器裏獲取,那麼對象的構建操作就被spring容器接管,所以它被稱為控制反轉,控制反轉的意思就是本來屬於java程序裏構建對象的功能交由容器接管,依賴注入就是當程序要使用某個對象時候,容器會把它注入到程序裏,這就叫做依賴注入。在java開發裏我們想使用某個類提供的功能,有兩種方式,一種就是構造一個新的類,新的類繼承該類,另一種方式則是將某個類定義在新類裏,那麼兩個類之間就建立一種關聯關係,spring的ioc容器就是實現了這種關聯關係(記住不是繼承關係哦),那麼某個類要被賦予到新類有哪些辦法了?一般只有兩種:一種就是通過構造函數,一種就是通過setXXX方式,這也是spring容器使用到了兩種標準的注入方式。

不管是上面說的繼承方式,還是關聯方式其實都是增強目標對象能力的開發手段,在設計模式裏有一種代理模式,代理模式將繼承模式和關聯模式結合在一起使用,代理模式就是繼承模式和關聯模式的綜合體,不過這個綜合體的作用倒不是解決對象注入的問題,而是為具體操作對象找到一個保姆或者是祕書,這就和小說裏的二號首長一樣,這個二號首長對外代表了具體的實例對象,實例對象的入口和出口都是通過這個二號首長,因為具體的實例對象是一號首長,一號首長是要幹大事的,所以一些事務性,重複性的工作例如泡茶,安排車子,這樣的工作是不用勞煩一號首長的大駕,而是二號首長幫忙解決的,這就是aop的思想,aop解決程序開發裏事務性,和核心業務無關的問題,但這些問題對於業務場景的實現是很有必要的,在實際開發裏aop也是節省代碼的一種方式。

Spring的核心技術的作用本質就是一個 溝通機制,spring總是盡全力的讓溝通的雙方信息暢通,同時降低雙方的溝通成本,在現實機構裏一個善於溝通的人肯定是該公司的領導,很會溝通的領導能調動起各種資源的積極性,善於溝通的領導就會做到海納百川,讓各種不同人追隨他,所以當今的spring就是一個大框,什麼都可以往裡裝。

Spring很像銀行,它不能直接創造物質財富,但是一切資源都要通過它進行流通,它能控制經濟發展的走向,回到程序的世界,spring的作用是被標榜為程序之間的解耦,spring能降低不同模塊之間的耦合度,原因就是在程序開發裏不同模塊之間信息的溝通是通過對象傳遞完成的,而對象能否順利傳遞就是要合理的構建好對象,而管理好對象的構建方式就能管理好對象傳遞,這就是spring給系統架構設計帶來的好處。

來源:CSDN

原文:blog.csdn.net/Melod_bc/


推薦閱讀:
相關文章