'華為技術總監經驗分享:SpringMVC系統架構與流程回顧'

"
"
華為技術總監經驗分享:SpringMVC系統架構與流程回顧

web開發經歷了很漫長的時間,在國內也快有十幾年的時間了。從最開始的進程級到現在的MVC經歷了很多的改進和優化,本篇就主要複習瞭解下Spring MVC相關的知識。

發展歷程

第一階段 CGI進程響應

這一階段,服務器比較弱,請求也很簡單,就是用戶發一個請求,服務器接收後新建進程,然後返回結果。

"
華為技術總監經驗分享:SpringMVC系統架構與流程回顧

web開發經歷了很漫長的時間,在國內也快有十幾年的時間了。從最開始的進程級到現在的MVC經歷了很多的改進和優化,本篇就主要複習瞭解下Spring MVC相關的知識。

發展歷程

第一階段 CGI進程響應

這一階段,服務器比較弱,請求也很簡單,就是用戶發一個請求,服務器接收後新建進程,然後返回結果。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


這種方式一看代價就很大,每次都新建進程,很麻煩。

第二階段 Servlet線程級別響應

Servlet結構跟上面差不多,只不過每次都只是新建一個線程,這樣代價就小很多了。

Servlet的生命週期有四個階段:

1 加載和實例化:啟動Tomcat這種Servlet容器,容器會根據配置文件加載Servlet類,並通過new方法進行實例化

2 初始化:然後調用init()方法初始化,每個Servlet只會初始化一次,可以理解為單例模式

3 請求處理:當服務器接收請求後,接收請求的線程找到對應的Servlet,調用service()方法響應。因此會存在多個線程同時掉用一個Servlet實例的情況,因此這裡會有線程安全問題的!

4 銷燬:Tomcat關閉時,調用destroy()銷燬容器。

那麼整體的流程是這樣的:

1 客戶端發送請求,Tomcat服務器接收請求後,封裝HttpRequest對象和HttpResponse對象

2 根據配置文件xml去查找匹配的servlet-name,並加載對應的servlet

3 如果之前沒有加載過,那麼加載並進行實例化和初始化;如果加載過,則直接調用service方法處理

4 把處理的結果封裝到HttpResponse中返回

那麼如何回答Serlet到底是不是線程安全呢?可以說它本身是無狀態的,如果沒有在裡面自己新增一個什麼count++的操作,就不會存在線程安全問題。

如果想要避免線程安全問題,可以採用下面的思路:

1 避免使用實例變量

2 避免使用非線程安全的集合

3 訪問外部可寫文件需要加鎖

總結來說,這裡只要注意Servlet的生命週期以及線程安全問題即可。

第三階段 JSP+Model1

這個階段引入了JSP技術,即Java Server Page,它是一種把HTML和Java混合在一起的技術語言。我記得我剛學習Java的時候,就是用這種JSP的技術,如果頁面稍微複雜一點,代碼就會特別混亂。

"
華為技術總監經驗分享:SpringMVC系統架構與流程回顧

web開發經歷了很漫長的時間,在國內也快有十幾年的時間了。從最開始的進程級到現在的MVC經歷了很多的改進和優化,本篇就主要複習瞭解下Spring MVC相關的知識。

發展歷程

第一階段 CGI進程響應

這一階段,服務器比較弱,請求也很簡單,就是用戶發一個請求,服務器接收後新建進程,然後返回結果。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


這種方式一看代價就很大,每次都新建進程,很麻煩。

第二階段 Servlet線程級別響應

Servlet結構跟上面差不多,只不過每次都只是新建一個線程,這樣代價就小很多了。

Servlet的生命週期有四個階段:

1 加載和實例化:啟動Tomcat這種Servlet容器,容器會根據配置文件加載Servlet類,並通過new方法進行實例化

2 初始化:然後調用init()方法初始化,每個Servlet只會初始化一次,可以理解為單例模式

3 請求處理:當服務器接收請求後,接收請求的線程找到對應的Servlet,調用service()方法響應。因此會存在多個線程同時掉用一個Servlet實例的情況,因此這裡會有線程安全問題的!

4 銷燬:Tomcat關閉時,調用destroy()銷燬容器。

那麼整體的流程是這樣的:

1 客戶端發送請求,Tomcat服務器接收請求後,封裝HttpRequest對象和HttpResponse對象

2 根據配置文件xml去查找匹配的servlet-name,並加載對應的servlet

3 如果之前沒有加載過,那麼加載並進行實例化和初始化;如果加載過,則直接調用service方法處理

4 把處理的結果封裝到HttpResponse中返回

那麼如何回答Serlet到底是不是線程安全呢?可以說它本身是無狀態的,如果沒有在裡面自己新增一個什麼count++的操作,就不會存在線程安全問題。

如果想要避免線程安全問題,可以採用下面的思路:

1 避免使用實例變量

2 避免使用非線程安全的集合

3 訪問外部可寫文件需要加鎖

總結來說,這裡只要注意Servlet的生命週期以及線程安全問題即可。

第三階段 JSP+Model1

這個階段引入了JSP技術,即Java Server Page,它是一種把HTML和Java混合在一起的技術語言。我記得我剛學習Java的時候,就是用這種JSP的技術,如果頁面稍微複雜一點,代碼就會特別混亂。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


不過這種方式也引入了一種前後端分離開發的合作模式,即會有專門的開發靜態頁面的人,開發完後把頁面交給後段程序猿,增量的開發Java相關的後端處理和數據展現相關的功能。

"
華為技術總監經驗分享:SpringMVC系統架構與流程回顧

web開發經歷了很漫長的時間,在國內也快有十幾年的時間了。從最開始的進程級到現在的MVC經歷了很多的改進和優化,本篇就主要複習瞭解下Spring MVC相關的知識。

發展歷程

第一階段 CGI進程響應

這一階段,服務器比較弱,請求也很簡單,就是用戶發一個請求,服務器接收後新建進程,然後返回結果。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


這種方式一看代價就很大,每次都新建進程,很麻煩。

第二階段 Servlet線程級別響應

Servlet結構跟上面差不多,只不過每次都只是新建一個線程,這樣代價就小很多了。

Servlet的生命週期有四個階段:

1 加載和實例化:啟動Tomcat這種Servlet容器,容器會根據配置文件加載Servlet類,並通過new方法進行實例化

2 初始化:然後調用init()方法初始化,每個Servlet只會初始化一次,可以理解為單例模式

3 請求處理:當服務器接收請求後,接收請求的線程找到對應的Servlet,調用service()方法響應。因此會存在多個線程同時掉用一個Servlet實例的情況,因此這裡會有線程安全問題的!

4 銷燬:Tomcat關閉時,調用destroy()銷燬容器。

那麼整體的流程是這樣的:

1 客戶端發送請求,Tomcat服務器接收請求後,封裝HttpRequest對象和HttpResponse對象

2 根據配置文件xml去查找匹配的servlet-name,並加載對應的servlet

3 如果之前沒有加載過,那麼加載並進行實例化和初始化;如果加載過,則直接調用service方法處理

4 把處理的結果封裝到HttpResponse中返回

那麼如何回答Serlet到底是不是線程安全呢?可以說它本身是無狀態的,如果沒有在裡面自己新增一個什麼count++的操作,就不會存在線程安全問題。

如果想要避免線程安全問題,可以採用下面的思路:

1 避免使用實例變量

2 避免使用非線程安全的集合

3 訪問外部可寫文件需要加鎖

總結來說,這裡只要注意Servlet的生命週期以及線程安全問題即可。

第三階段 JSP+Model1

這個階段引入了JSP技術,即Java Server Page,它是一種把HTML和Java混合在一起的技術語言。我記得我剛學習Java的時候,就是用這種JSP的技術,如果頁面稍微複雜一點,代碼就會特別混亂。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


不過這種方式也引入了一種前後端分離開發的合作模式,即會有專門的開發靜態頁面的人,開發完後把頁面交給後段程序猿,增量的開發Java相關的後端處理和數據展現相關的功能。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧

大體的流程是

1 用戶發送請求給服務器,服務器對應的JSP頁面接收到請求。

2 JSP會被編譯成Servlet,模式就跟之前一樣了

3 最後填充數據,返回即可。也就是說,它其實就是把之前頁面視圖的部分和Servlet的部分融合到一起而已。

現在基本上已經看不到這種技術模式了。

第四階段 前後端分離+Spring MVC

現在大部分的模式就是這樣的,只是在後段展現上略有不同。這種模式主要的關鍵是那個控制器,它負責任務的分發請求,以及數據的返回。

"
華為技術總監經驗分享:SpringMVC系統架構與流程回顧

web開發經歷了很漫長的時間,在國內也快有十幾年的時間了。從最開始的進程級到現在的MVC經歷了很多的改進和優化,本篇就主要複習瞭解下Spring MVC相關的知識。

發展歷程

第一階段 CGI進程響應

這一階段,服務器比較弱,請求也很簡單,就是用戶發一個請求,服務器接收後新建進程,然後返回結果。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


這種方式一看代價就很大,每次都新建進程,很麻煩。

第二階段 Servlet線程級別響應

Servlet結構跟上面差不多,只不過每次都只是新建一個線程,這樣代價就小很多了。

Servlet的生命週期有四個階段:

1 加載和實例化:啟動Tomcat這種Servlet容器,容器會根據配置文件加載Servlet類,並通過new方法進行實例化

2 初始化:然後調用init()方法初始化,每個Servlet只會初始化一次,可以理解為單例模式

3 請求處理:當服務器接收請求後,接收請求的線程找到對應的Servlet,調用service()方法響應。因此會存在多個線程同時掉用一個Servlet實例的情況,因此這裡會有線程安全問題的!

4 銷燬:Tomcat關閉時,調用destroy()銷燬容器。

那麼整體的流程是這樣的:

1 客戶端發送請求,Tomcat服務器接收請求後,封裝HttpRequest對象和HttpResponse對象

2 根據配置文件xml去查找匹配的servlet-name,並加載對應的servlet

3 如果之前沒有加載過,那麼加載並進行實例化和初始化;如果加載過,則直接調用service方法處理

4 把處理的結果封裝到HttpResponse中返回

那麼如何回答Serlet到底是不是線程安全呢?可以說它本身是無狀態的,如果沒有在裡面自己新增一個什麼count++的操作,就不會存在線程安全問題。

如果想要避免線程安全問題,可以採用下面的思路:

1 避免使用實例變量

2 避免使用非線程安全的集合

3 訪問外部可寫文件需要加鎖

總結來說,這裡只要注意Servlet的生命週期以及線程安全問題即可。

第三階段 JSP+Model1

這個階段引入了JSP技術,即Java Server Page,它是一種把HTML和Java混合在一起的技術語言。我記得我剛學習Java的時候,就是用這種JSP的技術,如果頁面稍微複雜一點,代碼就會特別混亂。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


不過這種方式也引入了一種前後端分離開發的合作模式,即會有專門的開發靜態頁面的人,開發完後把頁面交給後段程序猿,增量的開發Java相關的後端處理和數據展現相關的功能。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧

大體的流程是

1 用戶發送請求給服務器,服務器對應的JSP頁面接收到請求。

2 JSP會被編譯成Servlet,模式就跟之前一樣了

3 最後填充數據,返回即可。也就是說,它其實就是把之前頁面視圖的部分和Servlet的部分融合到一起而已。

現在基本上已經看不到這種技術模式了。

第四階段 前後端分離+Spring MVC

現在大部分的模式就是這樣的,只是在後段展現上略有不同。這種模式主要的關鍵是那個控制器,它負責任務的分發請求,以及數據的返回。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


架構模型就如上面所示,不過在SpringMVC中,控制器有兩種,一種是前端控制器,一種是應用控制器。

"
華為技術總監經驗分享:SpringMVC系統架構與流程回顧

web開發經歷了很漫長的時間,在國內也快有十幾年的時間了。從最開始的進程級到現在的MVC經歷了很多的改進和優化,本篇就主要複習瞭解下Spring MVC相關的知識。

發展歷程

第一階段 CGI進程響應

這一階段,服務器比較弱,請求也很簡單,就是用戶發一個請求,服務器接收後新建進程,然後返回結果。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


這種方式一看代價就很大,每次都新建進程,很麻煩。

第二階段 Servlet線程級別響應

Servlet結構跟上面差不多,只不過每次都只是新建一個線程,這樣代價就小很多了。

Servlet的生命週期有四個階段:

1 加載和實例化:啟動Tomcat這種Servlet容器,容器會根據配置文件加載Servlet類,並通過new方法進行實例化

2 初始化:然後調用init()方法初始化,每個Servlet只會初始化一次,可以理解為單例模式

3 請求處理:當服務器接收請求後,接收請求的線程找到對應的Servlet,調用service()方法響應。因此會存在多個線程同時掉用一個Servlet實例的情況,因此這裡會有線程安全問題的!

4 銷燬:Tomcat關閉時,調用destroy()銷燬容器。

那麼整體的流程是這樣的:

1 客戶端發送請求,Tomcat服務器接收請求後,封裝HttpRequest對象和HttpResponse對象

2 根據配置文件xml去查找匹配的servlet-name,並加載對應的servlet

3 如果之前沒有加載過,那麼加載並進行實例化和初始化;如果加載過,則直接調用service方法處理

4 把處理的結果封裝到HttpResponse中返回

那麼如何回答Serlet到底是不是線程安全呢?可以說它本身是無狀態的,如果沒有在裡面自己新增一個什麼count++的操作,就不會存在線程安全問題。

如果想要避免線程安全問題,可以採用下面的思路:

1 避免使用實例變量

2 避免使用非線程安全的集合

3 訪問外部可寫文件需要加鎖

總結來說,這裡只要注意Servlet的生命週期以及線程安全問題即可。

第三階段 JSP+Model1

這個階段引入了JSP技術,即Java Server Page,它是一種把HTML和Java混合在一起的技術語言。我記得我剛學習Java的時候,就是用這種JSP的技術,如果頁面稍微複雜一點,代碼就會特別混亂。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


不過這種方式也引入了一種前後端分離開發的合作模式,即會有專門的開發靜態頁面的人,開發完後把頁面交給後段程序猿,增量的開發Java相關的後端處理和數據展現相關的功能。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧

大體的流程是

1 用戶發送請求給服務器,服務器對應的JSP頁面接收到請求。

2 JSP會被編譯成Servlet,模式就跟之前一樣了

3 最後填充數據,返回即可。也就是說,它其實就是把之前頁面視圖的部分和Servlet的部分融合到一起而已。

現在基本上已經看不到這種技術模式了。

第四階段 前後端分離+Spring MVC

現在大部分的模式就是這樣的,只是在後段展現上略有不同。這種模式主要的關鍵是那個控制器,它負責任務的分發請求,以及數據的返回。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


架構模型就如上面所示,不過在SpringMVC中,控制器有兩種,一種是前端控制器,一種是應用控制器。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


大致的流程為:

1 用戶發送請求,前端控制器統一接收

2 然後根據不同的規則分發到對應的應用控制器,比如根據URL

3 應用控制器在調用邏輯代碼處理

4 最後層層返回。

目前一般的公司,都是採用前後端分離的技術結構。

1 前端是Vue.js或者AngularJS再或者是JQuery,通過Http的方式發送到後端。

2 後端接收請求後按照一定的業務規則處理,然後把數據返回給前端。

3 前端通過JavaScript代碼進行解析,瀏覽器渲染展現。

"
華為技術總監經驗分享:SpringMVC系統架構與流程回顧

web開發經歷了很漫長的時間,在國內也快有十幾年的時間了。從最開始的進程級到現在的MVC經歷了很多的改進和優化,本篇就主要複習瞭解下Spring MVC相關的知識。

發展歷程

第一階段 CGI進程響應

這一階段,服務器比較弱,請求也很簡單,就是用戶發一個請求,服務器接收後新建進程,然後返回結果。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


這種方式一看代價就很大,每次都新建進程,很麻煩。

第二階段 Servlet線程級別響應

Servlet結構跟上面差不多,只不過每次都只是新建一個線程,這樣代價就小很多了。

Servlet的生命週期有四個階段:

1 加載和實例化:啟動Tomcat這種Servlet容器,容器會根據配置文件加載Servlet類,並通過new方法進行實例化

2 初始化:然後調用init()方法初始化,每個Servlet只會初始化一次,可以理解為單例模式

3 請求處理:當服務器接收請求後,接收請求的線程找到對應的Servlet,調用service()方法響應。因此會存在多個線程同時掉用一個Servlet實例的情況,因此這裡會有線程安全問題的!

4 銷燬:Tomcat關閉時,調用destroy()銷燬容器。

那麼整體的流程是這樣的:

1 客戶端發送請求,Tomcat服務器接收請求後,封裝HttpRequest對象和HttpResponse對象

2 根據配置文件xml去查找匹配的servlet-name,並加載對應的servlet

3 如果之前沒有加載過,那麼加載並進行實例化和初始化;如果加載過,則直接調用service方法處理

4 把處理的結果封裝到HttpResponse中返回

那麼如何回答Serlet到底是不是線程安全呢?可以說它本身是無狀態的,如果沒有在裡面自己新增一個什麼count++的操作,就不會存在線程安全問題。

如果想要避免線程安全問題,可以採用下面的思路:

1 避免使用實例變量

2 避免使用非線程安全的集合

3 訪問外部可寫文件需要加鎖

總結來說,這裡只要注意Servlet的生命週期以及線程安全問題即可。

第三階段 JSP+Model1

這個階段引入了JSP技術,即Java Server Page,它是一種把HTML和Java混合在一起的技術語言。我記得我剛學習Java的時候,就是用這種JSP的技術,如果頁面稍微複雜一點,代碼就會特別混亂。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


不過這種方式也引入了一種前後端分離開發的合作模式,即會有專門的開發靜態頁面的人,開發完後把頁面交給後段程序猿,增量的開發Java相關的後端處理和數據展現相關的功能。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧

大體的流程是

1 用戶發送請求給服務器,服務器對應的JSP頁面接收到請求。

2 JSP會被編譯成Servlet,模式就跟之前一樣了

3 最後填充數據,返回即可。也就是說,它其實就是把之前頁面視圖的部分和Servlet的部分融合到一起而已。

現在基本上已經看不到這種技術模式了。

第四階段 前後端分離+Spring MVC

現在大部分的模式就是這樣的,只是在後段展現上略有不同。這種模式主要的關鍵是那個控制器,它負責任務的分發請求,以及數據的返回。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


架構模型就如上面所示,不過在SpringMVC中,控制器有兩種,一種是前端控制器,一種是應用控制器。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧


大致的流程為:

1 用戶發送請求,前端控制器統一接收

2 然後根據不同的規則分發到對應的應用控制器,比如根據URL

3 應用控制器在調用邏輯代碼處理

4 最後層層返回。

目前一般的公司,都是採用前後端分離的技術結構。

1 前端是Vue.js或者AngularJS再或者是JQuery,通過Http的方式發送到後端。

2 後端接收請求後按照一定的業務規則處理,然後把數據返回給前端。

3 前端通過JavaScript代碼進行解析,瀏覽器渲染展現。

華為技術總監經驗分享:SpringMVC系統架構與流程回顧

源碼細節

經過上面的描述,對SpringMVC的整體流程應該有了大致的瞭解。但是經典的那句話,talk is cheap, show me your code。

這個Dispacther分發器是怎麼實現的呢?其實它就是一個普通的Servlet而已,只不過Servlet攔截的請求時所有的請求而已:

<servlet> 
<servlet-name>test</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>test</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>

然後這個Servlet會調用doDispatch方法,主要的內容都在這裡

protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
省略代碼
try {
doDispatch(request, response);
}
finally {
省略代碼
}
}

doDispatch方法則包含了剛才描述的種種步驟:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
省略
try {
省略
try {
// Determine handler for the current request.獲得處理器映射
mappedHandler = getHandler(processedRequest);
// Determine handler adapter for the current request.獲得適配器對象
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
// Actually invoke the handler.實際處理
mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
//最後返回結果
}
}
}

常用的經驗

1 如果時開發Restful風格的後端程序,即通過Http以及GET、POST、PUT、DELETE等進行數據的增刪改查,那麼可以直接使用 @RestController 註解

2 通常工程設計都會分為幾層, Controller , Service , Mapper 如果有分層,可以用 @Service 和 @Autowired 註解搭配自動注入

3 如果使用 @Service ,最好直接寫上Service的名字,如 @Service(value = "myService") 不然如果你的名字是ABCService,默認的Service名字大小寫會容易引發BUG,尤其是需要手動查找某個bean時。

4 一般為了讓代碼簡潔,Controller參數列表可以封裝一個JavaBean類,用來自動封裝參數,是用的時候會方便得多。

需要的Java架構師方面的資料可以關注之後私信哈,回覆“資料”領取免費架構視頻資料,記得要點贊轉發噢!!!

"

相關推薦

推薦中...