Java修煉之道--Web

原做地址:https://github.com/frank-lam/2019_campus_applyjavascript

前言

在本文中將總結 Java Web 開發技術和相關框架的核心知識。因框架知識體系比較龐大,具體每一個框架的使用我將放在 ../JavaWeb 這個目錄下,包含 Spring、Strust二、Hibernate、Spring Boot 等框架。html

  • Spring
  • Strust2
  • Hibernate
  • Mybatis
  • Spring MVC
  • Spring Boot
  • Dubbo

在面試指南中將列舉面試中常見的考點,包含Servlet、JSP、Spring、中間件等常考Java Web框架知識前端

參考資料:java

1、Servlet / JSP / Web

1. 什麼是Servlet

Servlet 是在服務器上運行的小程序。一個 servlet 就是一個 Java 類,而且能夠經過 「請求—響應」 編程模式來訪問的這個駐留在服務器內存裏的 servlet 程序。git

類的繼承關係以下:程序員

Servlet三種實現方式:github

  • 實現javax.servlet.Servlet接口web

  • 繼承javax.servlet.GenericServlet類
  • 繼承javax.servlet.http.HttpServlet類面試

  一般會去繼承HttpServlet類來完成Servlet。算法

2. Tomcat容器等級

Tomcat的容器分爲4個等級,Servlet的容器管理Context容器,一個Context對應一個Web工程。

3. Servlet執行流程

主要描述了從瀏覽器到服務器,再從服務器到瀏覽器的整個執行過程

瀏覽器請求

瀏覽器向服務器請求時,服務器不會直接執行咱們的類,而是到 web.xml 裏尋找路徑名
① 瀏覽器輸入訪問路徑後,攜帶了請求行,頭,體
② 根據訪問路徑找到已註冊的 servlet 名稱
③ 根據映射找到對應的 servlet 名
④ 根據根據 servlet 名找到咱們全限定類名,既咱們本身寫的類

服務器建立對象

① 服務器找到全限定類名後,經過反射建立對象,同時也建立了 servletConfig,裏面存放了一些初始化信息(注意服務器只會建立一次 servlet 對象,因此 servletConfig 也只有一個)

調用init方法

① 對象建立好以後,首先要執行 init 方法,可是咱們發現咱們自定義類下沒有 init 方法,因此程序會到其父類 HttpServlet 裏找
② 咱們發現 HttpServlet 裏也沒有 init 方法,因此繼續向上找,既向其父類 GenericServlet 中繼續尋找,在 GenericServlet 中咱們發現了 init 方法,則執行 init 方法(對接口 Servlet 中的 init 方法進行了重寫)

注意: 在 GenericServlet 中執行 public void init(ServletConfig config) 方法的時候,又調用了本身無參無方法體的 init() 方法,其目的是爲了方便開發者,若是開發者在初始化的過程當中須要實現一些功能,能夠重寫此方法。

調用service方法

接着,服務器會先建立兩個對象:ServletRequest 請求對象和 ServletResponse 響應對象,用來封裝瀏覽器的請求數據和封裝向瀏覽器的響應數據
① 接着服務器會默認在咱們寫的類裏尋找 service(ServletRequest req, ServletResponse res) 方法,可是 DemoServlet 中不存在,那麼會到其父類中尋找
② 到父類 HttpServlet 中發現有此方法,則直接調用此方法,並將以前建立好的兩個對象傳入
③ 而後將傳入的兩個參數強轉,並調用 HttpServlet 下的另外個 service 方法
④ 接着執行 service(HttpServletRequest req, HttpServletResponse resp)方法,在此方法內部進行了判斷請求方式,並執行doGet和doPost,可是doGet和doPost方法已經被咱們本身重寫了,因此會執行咱們重寫的方法
看到這裏,你或許有疑問:爲何咱們不直接重寫service方法?
由於若是重寫service方法的話,咱們須要將強轉,以及一系列的安全保護判斷從新寫一遍,會存在安全隱患

向瀏覽器響應

4. Servlet生命週期

  • void init(ServletConfig servletConfig):Servlet對象建立以後立刻執行的初始化方法,只執行一次;
  • void service(ServletRequest servletRequest, ServletResponse servletResponse):每次處理請求都是在調用這個方法,它會被調用屢次;
  • void destroy():在Servlet被銷燬以前調用,負責釋放 Servlet 對象佔用的資源的方法;

特性:

  • 線程不安全的,因此它的效率高。
  • 單例,一個類只有一個對象,固然可能存在多個 Servlet 類

Servlet 類由本身編寫,但對象由服務器來建立,並由服務器來調用相應的方法 

服務器啓動時 ( web.xml中配置load-on-startup=1,默認爲0 ) 或者第一次請求該 servlet 時,就會初始化一個 Servlet 對象,也就是會執行初始化方法 init(ServletConfig conf)

該 servlet 對象去處理全部客戶端請求,在 service(ServletRequest req,ServletResponse res) 方法中執行

最後服務器關閉時,纔會銷燬這個 servlet 對象,執行 destroy() 方法。


總結(面試會問):   

1)Servlet什麼時候建立

默認第一次訪問servlet時建立該對象(調用init()方法)

2)Servlet什麼時候銷燬

服務器關閉servlet就銷燬了(調用destroy()方法)

3)每次訪問必須執行的方法

public void service(ServletRequest arg0, ServletResponse arg1)

5. Tomcat裝載Servlet的三種狀況

  1. Servlet容器啓動時自動裝載某些Servlet,實現它只須要在web.xml文件中的 <servlet></servlet> 之間添加如下代碼:
<load-on-startup>1</load-on-startup>

  其中,數字越小表示優先級越高。

  例如:咱們在 web.xml 中設置 TestServlet2 的優先級爲 1,而 TestServlet1 的優先級爲 2,啓動和關閉Tomcat:優先級高的先啓動也先關閉。  

  1. 客戶端首次向某個Servlet發送請求

  2. Servlet 類被修改後,Tomcat 容器會從新裝載 Servlet。

6. forward和redirect

本節參考:《Java程序員面試筆試寶典》P172

  在設計 Web 應用程序時,常常須要把一個系統進行結構化設計,即按照模塊進行劃分,讓不一樣的 Servlet 來實現不一樣的功能,例如可讓其中一個 Servlet 接收用戶的請求,另一個 Servlet 來處理用戶的請求。爲了實現這種程序的模塊化,就須要保證在不一樣的 Servlet 之間能夠相互跳轉,而 Servlet 中主要有兩種實現跳轉的方式:forward 與 redirect 方式。

  forward 是服務器內部的重定向,服務器直接訪問目標地址的 URL,把那個 URL 的響應內容讀取過來,而客戶端並不知道,所以在客戶端瀏覽器的地址欄中不會顯示轉向後的地址,仍是原來的地址。因爲在整個定向的過程當中用的是同一個 Request,所以 forward 會將 Request 的信息帶到被定向的 JSP 或 Servlet 中使用。

  redirect 則是客戶端的重定向,是徹底的跳轉,即客戶端瀏覽器會獲取到跳轉後的地址,而後從新發送請求,所以瀏覽器中會顯示跳轉後的地址。同事,因爲這種方式比 forward 方式多了一次網絡請求,所以其效率要低於 forward 方式。須要注意的是,客戶端的重定向能夠經過設置特定的 HTTP 頭或改寫 JavaScript 腳本實現。

  下圖能夠更好的說明兩者的區別:

  鑑於以上的區別,通常當 forward 方式能夠知足需求時,儘量地使用 forward 方式。但在有些狀況下,例如,須要跳轉到下一個其餘服務器上的資源,則必須使用 redirect 方式。

引伸:filter的做用是什麼?主要實現什麼方法?

filter 使用戶能夠改變一個 request 而且修改一個 response。filter 不是一個 Servlet,它不能產生一個 response,但它可以在一個 request 到達 Servlet 以前預處理 request,也能夠在離開 Servlet 時處理 response。filter 實際上是一個 「Servlet Chaining」 (Servler 鏈)。

一個 filter 的做用包括如下幾個方面:

1)在 Servlet 被調用以前截獲

2)在 Servlet 被調用以前檢查 Servlet Request

3)根據須要修改 Request 頭和 Request 數據

4)根據須要修改 Response 頭和 Response 數據

5)在 Servlet 被調用以後截獲

7. Jsp和Servlet的區別

一、不一樣之處在哪?

  • Servlet 在 Java 代碼中經過 HttpServletResponse 對象動態輸出 HTML 內容
  • JSP 在靜態 HTML 內容中嵌入 Java 代碼,Java 代碼被動態執行後生成 HTML 內容

二、各自的特色

  • Servlet 可以很好地組織業務邏輯代碼,可是在 Java 源文件中經過字符串拼接的方式生成動態 HTML 內容會致使代碼維護困難、可讀性差
  • JSP 雖然規避了 Servlet 在生成 HTML 內容方面的劣勢,可是在 HTML 中混入大量、複雜的業務邏輯一樣也是不可取的

三、經過MVC雙劍合璧

既然 JSP 和 Servlet 都有自身的適用環境,那麼可否揚長避短,讓它們發揮各自的優點呢?答案是確定的——MVC(Model-View-Controller)模式很是適合解決這一問題。

MVC模式(Model-View-Controller)是軟件工程中的一種軟件架構模式,把軟件系統分爲三個基本部分:模型(Model)、視圖(View)和控制器(Controller):

  • Controller——負責轉發請求,對請求進行處理
  • View——負責界面顯示
  • Model——業務功能編寫(例如算法實現)、數據庫設計以及數據存取操做實現

在 JSP/Servlet 開發的軟件系統中,這三個部分的描述以下所示:


  1. Web 瀏覽器發送 HTTP 請求到服務端,被 Controller(Servlet) 獲取並進行處理(例如參數解析、請求轉發)
  2. Controller(Servlet) 調用核心業務邏輯——Model部分,得到結果
  3. Controller(Servlet) 將邏輯處理結果交給 View(JSP),動態輸出 HTML 內容
  4. 動態生成的 HTML 內容返回到瀏覽器顯示

MVC 模式在 Web 開發中的好處是很是明顯,它規避了 JSP 與 Servlet 各自的短板,Servlet 只負責業務邏輯而不會經過 out.append() 動態生成 HTML 代碼;JSP 中也不會充斥着大量的業務代碼。這大大提升了代碼的可讀性和可維護性。

8. tomcat和Servlet的聯繫

  Tomcat是Web應用服務器,是一個Servlet/JSP容器。Tomcat 做爲 Servlet 容器,負責處理客戶請求,把請求傳送給Servlet,並將Servlet的響應傳送回給客戶。而 Servlet 是一種運行在支持 Java 語言的服務器上的組件。Servlet最多見的用途是擴展 Java Web 服務器功能,提供很是安全的,可移植的,易於使用的CGI替代品。

  從 http 協議中的請求和響應能夠得知,瀏覽器發出的請求是一個請求文本,而瀏覽器接收到的也應該是一個響應文本。可是在上面這個圖中,並不知道是如何轉變的,只知道瀏覽器發送過來的請求也就是 request,咱們響應回去的就用 response。忽略了其中的細節,如今就來探究一下。

① Tomcat 將 http 請求文本接收並解析,而後封裝成 HttpServletRequest 類型的 request 對象,全部的 HTTP 頭數據讀能夠經過 request 對象調用對應的方法查詢到。

② Tomcat 同時會要響應的信息封裝爲 HttpServletResponse 類型的 response 對象,經過設置 response 屬性就能夠控制要輸出到瀏覽器的內容,而後將 response 交給 tomcat,tomcat 就會將其變成響應文本的格式發送給瀏覽器

Java Servlet API 是 Servlet 容器(tomcat) 和 servlet 之間的接口,它定義了 serlvet 的各類方法,還定義了 Servlet 容器傳送給 Servlet 的對象類,其中最重要的就是 ServletRequest 和 ServletResponse。因此說咱們在編寫 servlet 時,須要實現 Servlet 接口,按照其規範進行操做。

9. cookie和session的區別

相似這種面試題,實際上都屬於「開放性」問題,你扯到哪裏均可以。不過若是我是面試官的話,我仍是但願對方能作到一點——不要混淆 session 和 session 實現。

原本 session 是一個抽象概念,開發者爲了實現中斷和繼續等操做,將 user agent 和 server 之間一對一的交互,抽象爲「會話」,進而衍生出「會話狀態」,也就是 session 的概念。

而 cookie 是一個實際存在的東西,http 協議中定義在 header 中的字段。能夠認爲是 session 的一種後端無狀態實現。

而咱們今天常說的 「session」,是爲了繞開 cookie 的各類限制,一般藉助 cookie 自己和後端存儲實現的,一種更高級的會話狀態實現。

因此 cookie 和 session,你能夠認爲是同一層次的概念,也能夠認爲是不一樣層次的概念。具體到實現,session 由於 session id 的存在,一般要藉助 cookie 實現,但這並不是必要,只能說是通用性較好的一種實現方案。

引伸

  1. 因爲 HTTP 協議是無狀態的協議,因此服務端須要記錄用戶的狀態時,就須要用某種機制來識具體的用戶,這個機制就是 Session。典型的場景好比購物車,當你點擊下單按鈕時,因爲 HTTP 協議無狀態,因此並不知道是哪一個用戶操做的,因此服務端要爲特定的用戶建立了特定的 Session,用用於標識這個用戶,而且跟蹤用戶,這樣才知道購物車裏面有幾本書。這個 Session 是保存在服務端的,有一個惟一標識。在服務端保存Session 的方法不少,內存、數據庫、文件都有。集羣的時候也要考慮 Session 的轉移,在大型的網站,通常會有專門的 Session 服務器集羣,用來保存用戶會話,這個時候 Session 信息都是放在內存的,使用一些緩存服務好比 Memcached 之類的來放 Session。

  2. 思考一下服務端如何識別特定的客戶?

    這個時候 Cookie 就登場了。每次 HTTP 請求的時候,客戶端都會發送相應的 Cookie 信息到服務端。實際上大多數的應用都是用 Cookie 來實現 Session 跟蹤的,第一次建立 Session 的時候,服務端會在 HTTP 協議中告訴客戶端,須要在 Cookie 裏面記錄一個Session ID,之後每次請求把這個會話 ID 發送到服務器,我就知道你是誰了。有人問,若是客戶端的瀏覽器禁用了 Cookie 怎麼辦?通常這種狀況下,會使用一種叫作URL重寫的技術來進行會話跟蹤,即每次 HTTP 交互,URL後面都會被附加上一個諸如 sid=xxxxx 這樣的參數,服務端據此來識別用戶。

  3. Cookie 其實還能夠用在一些方便用戶的場景下,設想你某次登錄過一個網站,下次登陸的時候不想再次輸入帳號了,怎麼辦?這個信息能夠寫到 Cookie 裏面,訪問網站的時候,網站頁面的腳本能夠讀取這個信息,就自動幫你把用戶名給填了,可以方便一下用戶。這也是 Cookie 名稱的由來,給用戶的一點甜頭。

因此,總結一下:

  • Session 是在服務端保存的一個數據結構,用來跟蹤用戶的狀態,這個數據能夠保存在集羣、數據庫、文件中;
  • Cookie 是客戶端保存用戶信息的一種機制,用來記錄用戶的一些信息,也是實現 Session 的一種方式。

10. JavaEE中的三層結構和MVC

作企業應用開發時,常常採用三層架構分層:表示層、業務層、持久層。表示層負責接收用戶請求、轉發請求、顯示數據等;業務層負責組織業務邏輯;持久層負責持久化業務對象。

這三個分層,每一層都有不一樣的模式,就是架構模式。表示層最經常使用的架構模式就是MVC。

所以,MVC 是三層架構中表示層最經常使用的架構模式。

MVC 是客戶端的一種設計模式,因此他自然就不考慮數據如何存儲的問題。做爲客戶端,只須要解決用戶界面、交互和業務邏輯就行了。在 MVC 模式中,View 負責的是用戶界面,Controller 負責交互,Model 負責業務邏輯。至於數據如何存儲和讀取,固然是由 Model 調用服務端的接口來完成。

在三層架構中,並無客戶端/服務端的概念,因此表示層、業務層的任務其實和 MVC 沒什麼區別,而持久層在 MVC 裏面是沒有的。

各層次的關係:表現層的控制->服務層->數據持久化層。

參考資料:

11. RESTful 架構

什麼是REST

能夠總結爲一句話:REST 是全部 Web 應用都應該遵照的架構設計指導原則。
Representational State Transfer,翻譯是」表現層狀態轉化」。
面向資源是 REST 最明顯的特徵,對於同一個資源的一組不一樣的操做。資源是服務器上一個可命名的抽象概念,資源是以名詞爲核心來組織的,首先關注的是名詞。REST要求,必須經過統一的接口來對資源執行各類操做。對於每一個資源只能執行一組有限的操做。(7個HTTP方法:GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS)

什麼是RESTful API

符合REST架構設計的API。

RESTful 風格

以豆瓣網爲例

  1. 應該儘可能將 API 部署在專用域名之下
    http://api.douban.com/v2/user/1000001?apikey=XXX

  2. 應該將 API 的版本號放入URL
    http://api.douban.com/v2/user/1000001?apikey=XXX

  3. 在 RESTful 架構中,每一個網址表明一種資源(resource),因此網址中不能有動詞,只能有名詞,並且所用的名詞每每與數據庫的表格名對應。通常來講,數據庫中的表都是同種記錄的」集合」(collection),因此 API 中的名詞也應該使用複數。
    http://api.douban.com/v2/book/:id (獲取圖書信息)
    http://api.douban.com/v2/movie/subject/:id (電影條目信息)
    http://api.douban.com/v2/music/:id (獲取音樂信息)
    http://api.douban.com/v2/event/:id (獲取同城活動)

  4. 對於資源的具體操做類型,由HTTP動詞表示。經常使用的HTTP動詞有下面四個(對應增/刪/改/查)。
    GETselect):從服務器取出資源(一項或多項)。
    eg. 獲取圖書信息 GET http://api.douban.com/v2/book/:id
    POSTcreate):在服務器新建一個資源。
    eg. 用戶收藏某本圖書 POST http://api.douban.com/v2/book/:id/collection

    PUTupdate):在服務器更新資源(客戶端提供改變後的完整資源)。
    eg. 用戶修改對某本圖書的收藏 PUT http://api.douban.com/v2/book/:id/collection

    DELETEdelete):從服務器刪除資源。
    eg. 用戶刪除某篇筆記 DELETE http://api.douban.com/v2/book/annotation/:id

  5. 若是記錄數量不少,服務器不可能都將它們返回給用戶。API應該提供參數,過濾返回結果

    ?limit=10:指定返回記錄的數量
    eg. 獲取圖書信息 GET http://api.douban.com/v2/book/:id?limit=10

  6. 服務器向用戶返回的狀態碼和提示信息
    每一個狀態碼錶明不一樣意思, 就像代號同樣

    2系 表明正常返回

    4系 表明數據異常

    5系 表明服務器異常

2、Spring

1. Spring IOC、AOP的理解、實現的原理,以及優勢

Spring的IoC容器是Spring的核心,Spring AOP是spring框架的重要組成部分

IOC

  • 個人理解
    • 正常的狀況下,好比有一個類,在類裏面有方法(不是靜態的方法),調用類裏面的方法,建立類的對象,使用對象調用方法,建立類對象的過程,須要new出來對象
    • 經過控制反轉,把對象的建立不是經過new方式實現,而是交給Spring配置建立類對象
    • IOC的意思是控件反轉也就是由容器控制程序之間的關係,這也是spring的優勢所在,把控件權交給了外部容器,以前的寫法,由程序代碼直接操控,而如今控制權由應用代碼中轉到了外部容器,控制權的轉移是所謂反轉。換句話說以前用new的方式獲取對象,如今由spring給你至於怎麼給你就是di了。
  • Spring IOC實現原理
    • 建立xml配置文件,配置要建立的對象類
    • 經過反射建立實例;
    • 獲取須要注入的接口實現類並將其賦值給該接口。
  • 優勢

    • 解耦合,開發更方便組織分工
    • 高層不依賴於底層(依賴倒置)
    • 是應用更容易測試
    • 由於把對象生成放在了XML裏定義,因此當咱們須要換一個實現子類將會變成很簡單(通常這樣的對象都是現實於某種接口的),只要修改XML就能夠了,這樣咱們甚至能夠實現對象的熱插撥

AOP

  • 個人理解

    • AOP(Aspect Oriented Programming )稱爲面向切面編程,擴展功能不是修改源代碼實現,在程序開發中主要用來解決一些系統層面上的問題,好比日誌,事務,權限等待,Struts2的攔截器設計就是基於AOP的思想,是個比較經典的例子。
    • 面向切面編程(aop)是對面向對象編程(oop)的補充
    • 面向切面編程提供聲明式事務管理
    • AOP就是典型的代理模式的體現
  • Spring AOP實現原理

    • 動態代理(利用反射和動態編譯將代理模式變成動態的)

    • JDK的動態代理

      • JDK內置的Proxy動態代理能夠在運行時動態生成字節碼,而不必針對每一個類編寫代理類
      • JDKProxy返回動態代理類,是目標類所實現接口的另外一個實現版本,它實現了對目標類的代理(如同UserDAOProxy與UserDAOImp的關係)
    • cglib動態代理

      • CGLibProxy返回的動態代理類,則是目標代理類的一個子類(代理類擴展了UserDaoImpl類)
      • cglib繼承被代理的類,重寫方法,織入通知,動態生成字節碼並運行
  • 優勢

    • 各個步驟之間的良好隔離性
    • 源代碼無關性
    • 鬆耦合
    • 易擴展
    • 代碼複用

2. 什麼是依賴注入,注入的方式有哪些

  • DI(依賴注入)

    • 所謂依賴注入,就是把底層類做爲參數傳入上層類,實現上層類對下層類的控制。DI依賴注入,向類裏面屬性注入值 ,依賴注入不能單獨存在,須要在IOC基礎上完成操做。
    • 使用set方法注入
    • 使用有參構造注入
    • 使用接口注入
    • 註解注入(@Autowire)

3. Spring IOC初始化過程


IOC容器的初始化分爲三個過程實現:

  • 第一個過程是Resource資源定位。這個Resouce指的是BeanDefinition的資源定位。這個過程就是容器找數據的過程,就像水桶裝水須要先找到水同樣。
  • 第二個過程是BeanDefinition的載入過程。這個載入過程是把用戶定義好的Bean表示成Ioc容器內部的數據結構,而這個容器內部的數據結構就是BeanDefition。
  • 第三個過程是向IOC容器註冊這些BeanDefinition的過程,這個過程就是將前面的BeanDefition保存到HashMap中的過程。

更詳細說明請閱讀:2 IOC容器初始化過程 - CSDN博客

參考資料:

4. 項目中Spring AOP用在什麼地方,爲何這麼用,切點,織入,通知用本身的話描述一下

  • Joinpoint(鏈接點)(重要)
    • 類裏面能夠被加強的方法,這些方法稱爲鏈接點
  • Pointcut(切入點)(重要)
    • 所謂切入點是指咱們要對哪些Joinpoint進行攔截的定義
  • Advice(通知/加強)(重要)
    • 所謂通知是指攔截到Joinpoint以後所要作的事情就是通知.通知分爲前置通知,後置通知,異常通知,最終通知,環繞通知(切面要完成的功能)
  • Aspect(切面)
    • 是切入點和通知(引介)的結合
  • Introduction(引介)
    • 引介是一種特殊的通知在不修改類代碼的前提下, Introduction能夠在運行期爲類動態地添加一些方法或Field.
  • Target(目標對象)
    • 代理的目標對象(要加強的類)
  • Weaving(織入)
    • 是把加強應用到目標的過程,把advice 應用到 target的過程
  • Proxy(代理)
    • 一個類被AOP織入加強後,就產生一個結果代理類

AOP(Aspect Oriented Programming )稱爲面向切面編程,擴展功能不是修改源代碼實現,在程序開發中主要用來解決一些系統層面上的問題,好比日誌,事務,權限等待,Struts2的攔截器設計就是基於AOP的思想,是個比較經典的例子。

5. AOP動態代理2種實現原理,他們的區別是什麼?

  • 動態代理與cglib實現的區別
    • JDK動態代理只能對實現了接口的類生成代理,而不能針對類.
    • cglib是針對類實現代理,主要是對指定的類生成一個子類,覆蓋其中的方法由於是繼承,因此該類或方法最好不要聲明成final。
    • JDK代理是不須要以來第三方的庫,只要JDK環境就能夠進行代理
    • cglib必須依賴於cglib的類庫,可是它須要類來實現任何接口代理的是指定的類生成一個子類,覆蓋其中的方法,是一種繼承

6. Struts攔截器和Spring AOP區別

Struts2攔截器淺析-慕課網
https://www.imooc.com/learn/450

7. Spring 是如何管理事務的,事務管理機制

事務管理能夠幫助咱們保證數據的一致性,對應企業的實際應用很重要。

Spring的事務機制包括聲明式事務和編程式事務。

  • 編程式事務管理:Spring推薦使用TransactionTemplate,實際開發中使用聲明式事務較多。
  • 聲明式事務管理:將咱們從複雜的事務處理中解脫出來,獲取鏈接,關閉鏈接、事務提交、回滾、異常處理等這些操做都不用咱們處理了,Spring都會幫咱們處理。

聲明式事務管理使用了AOP面向切面編程實現的,本質就是在目標方法執行先後進行攔截。在目標方法執行前加入或建立一個事務,在執行方法執行後,根據實際狀況選擇提交或是回滾事務

如何管理的

Spring事務管理主要包括3個接口,Spring的事務主要是由它們(PlatformTransactionManager,TransactionDefinition,TransactionStatus)三個共同完成的。

1. PlatformTransactionManager:事務管理器–主要用於平臺相關事務的管理

主要有三個方法:

  • commit 事務提交;
  • rollback 事務回滾;
  • getTransaction 獲取事務狀態。

2. TransactionDefinition:事務定義信息–用來定義事務相關的屬性,給事務管理器PlatformTransactionManager使用

這個接口有下面四個主要方法:

  • getIsolationLevel:獲取隔離級別;
  • getPropagationBehavior:獲取傳播行爲;
  • getTimeout:獲取超時時間;
  • isReadOnly:是否只讀(保存、更新、刪除時屬性變爲false–可讀寫,查詢時爲true–只讀)

事務管理器可以根據這個返回值進行優化,這些事務的配置信息,均可以經過配置文件進行配置。

3. TransactionStatus:事務具體運行狀態–事務管理過程當中,每一個時間點事務的狀態信息。

例如它的幾個方法:

  • hasSavepoint():返回這個事務內部是否包含一個保存點,
  • isCompleted():返回該事務是否已完成,也就是說,是否已經提交或回滾
  • isNewTransaction():判斷當前事務是不是一個新事務

聲明式事務的優缺點

  • 優勢:不須要在業務邏輯代碼中編寫事務相關代碼,只須要在配置文件配置或使用註解(@Transaction),這種方式沒有侵入性。
  • 缺點:聲明式事務的最細粒度做用於方法上,若是像代碼塊也有事務需求,只能變通下,將代碼塊變爲方法。

http://blog.csdn.net/jie_liang/article/details/77600742

8. Spring中bean加載機制,生命週期

加載機制

【Spring】詳解Spring中Bean的加載 - weknow619 - 博客園
https://www.cnblogs.com/weknow619/p/6673667.html

生命週期

在傳統的Java應用中,bean的生命週期很簡單。使用Java關鍵字new進行bean實例化,而後該bean就可使用了。一旦該bean再也不被使用,則由Java自動進行垃圾回收。

相比之下,Spring容器中的bean的生命週期就顯得相對複雜多了。正確理解Spring bean的生命週期很是重要,由於你或許要利用Spring提供的擴展點來自定義bean的建立過程。下圖展現了bean裝載到Spring應用上下文中的一個典型的生命週期過程。


上圖bean在Spring容器中從建立到銷燬經歷了若干階段,每一階段均可以針對Spring如何管理bean進行個性化定製

正如你所見,在bean準備就緒以前,bean工廠執行了若干啓動步驟。咱們對上圖進行詳細描述:

  1. Spring 對 Bean 進行實例化;
    • 至關於程序中的new Xx()
  2. Spring 將值和 Bean 的引用注入進 Bean 對應的屬性中;
  3. 若是Bean實現了 BeanNameAware 接口,Spring 將 Bean 的 ID 傳遞給setBeanName()方法
    • 實現BeanNameAware清主要是爲了經過Bean的引用來得到Bean的ID,通常業務中是不多有在Bean的ID的
  4. 若是Bean實現了BeanFactoryAware接口,Spring將調用setBeanDactory(BeanFactory bf)方法並把BeanFactory容器實例做爲參數傳入。
    • 實現BeanFactoryAware 主要目的是爲了獲取Spring容器,如Bean經過Spring容器發佈事件等
  5. 若是Bean實現了ApplicationContextAwaer接口,Spring容器將調用setApplicationContext(ApplicationContext ctx)方法,將bean所在的應用上下文的引用傳入進來
    • 做用與BeanFactory相似都是爲了獲取Spring容器,不一樣的是Spring容器在調用setApplicationContext方法時會把它本身做爲setApplicationContext 的參數傳入,而Spring容器在調用setBeanDactory前須要程序員本身指定(注入)setBeanDactory裏的參數BeanFactory
  6. 若是Bean實現了BeanPostProcess接口,Spring將調用它們的postProcessBeforeInitialization(預初始化)方法
    • 做用是在Bean實例建立成功後對進行加強處理,如對Bean進行修改,增長某個功能
  7. 若是Bean實現了InitializingBean接口,Spring將調用它們的afterPropertiesSet方法,做用與在配置文件中對Bean使用init-method聲明初始化的做用同樣,都是在Bean的所有屬性設置成功後執行的初始化方法。
  8. 若是Bean實現了BeanPostProcess接口,Spring將調用它們的postProcessAfterInitialization(後初始化)方法
    • 做用與6的同樣,只不過6是在Bean初始化前執行的,而這個是在Bean初始化後執行的,時機不一樣
  9. 通過以上的工做後,Bean將一直駐留在應用上下文中給應用使用,直到應用上下文被銷燬
  10. 若是Bean實現了DispostbleBean接口,Spring將調用它的destory方法,做用與在配置文件中對Bean使用destory-method屬性的做用同樣,都是在Bean實例銷燬前執行的方法。

9. Bean實例化的三種方式

  • 使用類的無參構造建立(此種方式用的最多)
  • 使用靜態工廠建立對象
  • 使用實例工廠建立對象

10. BeanFactory 和 FactoryBean的區別

  • BeanFactory是個Factory,也就是IOC容器或對象工廠,在Spring中,全部的Bean都是由BeanFactory(也就是IOC容器)來進行管理的,提供了實例化對象和拿對象的功能。
  • FactoryBean是個Bean,這個Bean不是簡單的Bean,而是一個能生產或者修飾對象生成的工廠Bean,它的實現與設計模式中的工廠模式和修飾器模式相似。

11. BeanFactory和ApplicationContext的區別

BeanFactory

是Spring裏面最低層的接口,提供了最簡單的容器的功能,只提供了實例化對象和拿對象的功能。

二者裝載bean的區別

  • BeanFactory:在啓動的時候不會去實例化Bean,中有從容器中拿Bean的時候纔會去實例化;
  • ApplicationContext:在啓動的時候就把全部的Bean所有實例化了。它還能夠爲Bean配置lazy-init=true來讓Bean延遲實例化;

咱們該用BeanFactory仍是ApplicationContent

BeanFactory 延遲實例化的優勢:

應用啓動的時候佔用資源不多,對資源要求較高的應用,比較有優點;

缺點:速度會相對來講慢一些。並且有可能會出現空指針異常的錯誤,並且經過bean工廠建立的bean生命週期會簡單一些

ApplicationContext 不延遲實例化的優勢:

  • 全部的Bean在啓動的時候都加載,系統運行的速度快;
  • 在啓動的時候全部的Bean都加載了,咱們就能在系統啓動的時候,儘早的發現系統中的配置問題
  • 建議web應用,在啓動的時候就把全部的Bean都加載了。

缺點:把費時的操做放到系統啓動中完成,全部的對象均可以預加載,缺點就是消耗服務器的內存

ApplicationContext其餘特色

除了提供BeanFactory所支持的全部功能外,ApplicationContext還有額外的功能

  • 默認初始化全部的Singleton,也能夠經過配置取消預初始化。
  • 繼承MessageSource,所以支持國際化。
  • 資源訪問,好比訪問URL和文件(ResourceLoader);
  • 事件機制,(有繼承關係)上下文 ,使得每個上下文都專一於一個特定的層次,好比應用的web層;
  • 同時加載多個配置文件。
  • 消息發送、響應機制(ApplicationEventPublisher);
  • 以聲明式方式啓動並建立Spring容器。

因爲ApplicationContext會預先初始化全部的Singleton Bean,因而在系統建立前期會有較大的系統開銷,但一旦ApplicationContext初始化完成,程序後面獲取Singleton Bean實例時候將有較好的性能。

也能夠爲bean設置lazy-init屬性爲true,即Spring容器將不會預先初始化該bean。

spring的AOP(經常使用的是攔截器)

通常攔截器都是實現HandlerInterceptor,其中有三個方法preHandle、postHandle、afterCompletion

  1. preHandle:執行controller以前執行
  2. postHandle:執行完controller,return modelAndView以前執行,主要操做modelAndView的值
  3. afterCompletion:controller返回後執行

spring載入多個上下文

不一樣項目使用不一樣分模塊策略,spring配置文件分爲

  • applicationContext.xml(主文件,包括JDBC配置,hibernate.cfg.xml,與全部的Service與DAO基類)
  • applicationContext-cache.xml(cache策略,包括hibernate的配置)
  • applicationContext-jmx.xml(JMX,調試hibernate的cache性能)
  • applicationContext-security.xml(acegi安全)
  • applicationContext-transaction.xml(事務)
  • moduleName-Service.xml
  • moduleName-dao.xml

12. ApplicationContext 上下文的生命週期

PS:能夠借鑑Servlet的生命週期,實例化、初始init、接收請求service、銷燬destroy;

Spring上下文中的Bean也相似,【Spring上下文的生命週期】

  1. 實例化一個Bean,也就是咱們一般說的new;
  2. 按照Spring上下文對實例化的Bean進行配置,也就是IOC注入
  3. 若是這個Bean實現了BeanNameAware接口,會調用它實現的setBeanName(String beanId)方法,此處傳遞的是Spring配置文件中Bean的ID;
  4. 若是這個Bean實現了BeanFactoryAware接口,會調用它實現的setBeanFactory(),傳遞的是Spring工廠自己(能夠用這個方法獲取到其餘Bean);
  5. 若是這個Bean實現了ApplicationContextAware接口,會調用setApplicationContext(ApplicationContext)方法,傳入Spring上下文,該方式一樣能夠實現步驟4,但比4更好,覺得ApplicationContext是BeanFactory的子接口,有更多的實現方法;
  6. 若是這個Bean關聯了BeanPostProcessor接口,將會調用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor常常被用做是Bean內容的更改,而且因爲這個是在Bean初始化結束時調用After方法,也可用於內存或緩存技術;
  7. 若是這個Bean在Spring配置文件中配置了init-method屬性會自動調用其配置的初始化方法;
  8. 若是這個Bean關聯了BeanPostProcessor接口,將會調用postAfterInitialization(Object obj, String s)方法;

注意:以上工做完成之後就能夠用這個Bean了,那這個Bean是一個single的,因此通常狀況下咱們調用同一個ID的Bean會是在內容地址相同的實例

  1. 當Bean再也不須要時,會通過清理階段,若是Bean實現了DisposableBean接口,會調用其實現的destroy方法
  2. 最後,若是這個Bean的Spring配置中配置了destroy-method屬性,會自動調用其配置的銷燬方法

以上10步驟能夠做爲面試或者筆試的模板,另外這裏描述的是應用Spring上下文Bean的生命週期,若是應用Spring的工廠也就是BeanFactory的話去掉第5步就Ok了;

13. Spring中autowire和resourse關鍵字的區別

@Resource和@Autowired都是作bean的注入時使用,其實@Resource並非Spring的註解,它的包是javax.annotation.Resource,須要導入,可是Spring支持該註解的注入。

一、共同點

二者均可以寫在字段和setter方法上。二者若是都寫在字段上,那麼就不須要再寫setter方法。

二、不一樣點

(1)@Autowired

@Autowired爲Spring提供的註解,須要導入包org.springframework.beans.factory.annotation.Autowired;只按照byType注入。

public class TestServiceImpl {
    // 下面兩種@Autowired只要使用一種便可
    @Autowired
    private UserDao userDao; // 用於字段上
    
    @Autowired
    public void setUserDao(UserDao userDao) { // 用於屬性的方法上
        this.userDao = userDao;
    }
}

@Autowired註解是按照類型(byType)裝配依賴對象,默認狀況下它要求依賴對象必須存在,若是容許null值,能夠設置它的required屬性爲false。若是咱們想使用按照名稱(byName)來裝配,能夠結合@Qualifier註解一塊兒使用。以下:

public class TestServiceImpl {
    @Autowired
    @Qualifier("userDao")
    private UserDao userDao; 
}

(2)@Resource

@Resource默認按照ByName自動注入,由J2EE提供,須要導入包javax.annotation.Resource。@Resource有兩個重要的屬性:name和type,而Spring將@Resource註解的name屬性解析爲bean的名字,而type屬性則解析爲bean的類型。因此,若是使用name屬性,則使用byName的自動注入策略,而使用type屬性時則使用byType自動注入策略。若是既不制定name也不制定type屬性,這時將經過反射機制使用byName自動注入策略。

public class TestServiceImpl {
    // 下面兩種@Resource只要使用一種便可
    @Resource(name="userDao")
    private UserDao userDao; // 用於字段上
    
    @Resource(name="userDao")
    public void setUserDao(UserDao userDao) { // 用於屬性的setter方法上
        this.userDao = userDao;
    }
}

注:最好是將@Resource放在setter方法上,由於這樣更符合面向對象的思想,經過set、get去操做屬性,而不是直接去操做屬性。

@Resource裝配順序:

  1. 若是同時指定了name和type,則從Spring上下文中找到惟一匹配的bean進行裝配,找不到則拋出異常。

  2. 若是指定了name,則從上下文中查找名稱(id)匹配的bean進行裝配,找不到則拋出異常。

  3. 若是指定了type,則從上下文中找到相似匹配的惟一bean進行裝配,找不到或是找到多個,都會拋出異常。
  4. 若是既沒有指定name,又沒有指定type,則自動按照byName方式進行裝配;若是沒有匹配,則回退爲一個原始類型進行匹配,若是匹配則自動裝配。

@Resource的做用至關於@Autowired,只不過@Autowired按照byType自動注入。

14. Spring的註解講一下,介紹Spring中的熟悉的註解

思考:spring怎麼知道應該哪些Java類當初bean類處理?

答案:使用配置文件或者註解的方式進行標識須要處理的java類!

一: 組件類註解

@Component :標準一個普通的spring Bean類。
@Repository:標註一個DAO組件類。
@Service:標註一個業務邏輯組件類。
@Controller:標註一個控制器組件類。

這些都是註解在平時的開發過程當中出鏡率極高,@Component、@Repository、@Service、@Controller實質上屬於同一類註解,用法相同,功能相同,區別在於標識組件的類型。@Component能夠代替@Repository、@Service、@Controller,由於這三個註解是被@Component標註的。以下代碼

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
    String value() default "";
}

舉例:

(1)當一個組件表明數據訪問層(DAO)的時候,咱們使用@Repository進行註解,以下

@Repository
public class HappyDaoImpl implements HappyDao{
private final static Logger LOGGER = LoggerFactory.getLogger(HappyDaoImpl .class);
public void  club(){
        //do something ,like drinking and singing
    }
}1234567

(2)當一個組件表明業務層時,咱們使用@Service進行註解,以下

@Service(value="goodClubService")
//使用@Service註解不加value ,默認名稱是clubService
public class ClubServiceImpl implements ClubService {
    @Autowired
    private ClubDao clubDao;

    public void doHappy(){
        //do some Happy
    }
 }12345678910

(3)當一個組件做爲前端交互的控制層,使用@Controller進行註解,以下

@Controller
public class HappyController {
    @Autowired //下面進行講解
    private ClubService clubService;

    // Control the people entering the Club
    // do something
}
/*Controller相關的註解下面進行詳細講解,這裏簡單引入@Controller*/

三、總結注意點

  1. 被註解的java類當作Bean實例,Bean實例的名稱默認是Bean類的首字母小寫,其餘部分不變。@Service也能夠自定義Bean名稱,可是必須是惟一的!
  2. 儘可能使用對應組件註解的類替換@Component註解,在spring將來的版本中,@Controller,@Service,@Repository會攜帶更多語義。而且便於開發和維護!
  3. 指定了某些類可做爲Spring Bean類使用後,最好還須要讓spring搜索指定路徑,在Spring配置文件加入以下配置:
<!-- 自動掃描指定包及其子包下的全部Bean類 -->
<context:component-scan base-package="org.springframework.*"/>

二:裝配bean時經常使用的註解

@Autowired:屬於Spring 的org.springframework.beans.factory.annotation包下,可用於爲類的屬性、構造器、方法進行注值
@Resource:不屬於spring的註解,而是來自於JSR-250位於java.annotation包下,使用該annotation爲目標bean指定協做者Bean。

...

更詳細請轉向:Spring經常使用註解介紹【經典總結】 - CSDN博客

15. Spring 中用到了那些設計模式?

Spring框架中使用到了大量的設計模式,下面列舉了比較有表明性的:

  • 代理模式—在AOP和remoting中被用的比較多。
  • 單例模式—在spring配置文件中定義的bean默認爲單例模式。
  • 模板方法—用來解決代碼重複的問題。好比. RestTemplate, JmsTemplate, JpaTemplate。
  • 工廠模式—BeanFactory用來建立對象的實例。
  • 適配器–spring aop
  • 裝飾器–spring data hashmapper
  • 觀察者– spring 時間驅動模型
  • 回調–Spring ResourceLoaderAware回調接口

工廠模式(Factory Method)

Spring容器就是實例化和管理Bean的工廠

工廠模式隱藏了建立類的細節,返回值一定是接口或者抽象類,而不是具體的某個對象,工廠類根據條件生成不一樣的子類實例。當獲得子類的實例後,就能夠調用基類中的方法,沒必要考慮返回的是哪個子類的實例。

這個很明顯,在各類BeanFactory以及ApplicationContext建立中都用到了;

Spring經過配置文件,就能夠管理全部的bean,而這些bean就是Spring工廠能產生的實例,所以,首先咱們在Spring配置文件中對兩個實例進行配置

單態模式【單例模式】(Singleton)

Spring默認將全部的Bean設置成 單例模式,即對全部的相同id的Bean的請求,都將返回同一個共享的Bean實例。這樣就能夠大大下降Java建立對象和銷燬時的系統開銷

使用Spring將Bean設置稱爲單例行爲,則無需本身完成單例模式。

| 能夠經過singleton=「true | false」 或者 scope=「?」來指定 |

適配器(Adapter)

在Spring的Aop中,使用的Advice(通知)來加強被代理類的功能。Spring實現這一AOP功能的原理就使用代理模式(一、JDK動態代理。二、CGLib字節碼生成技術代理。)對類進行方法級別的切面加強,即,生成被代理類的代理類, 並在代理類的方法前,設置攔截器,經過執行攔截器重的內容加強了代理方法的功能,實現的面向切面編程

代理(Proxy)

Spring實現了一種可以經過額外的方法調用完成任務的設計模式 - 代理設計模式,好比JdkDynamicAopProxy和Cglib2AopProxy。

代理設計模式的一個很好的例子是org.springframework.aop.framework.ProxyFactoryBean該工廠根據Spring bean構建AOP代理。該類實現了定義getObject()方法的FactoryBean接口。此方法用於將需求Bean的實例返回給bean factory。在這種狀況下,它不是返回的實例,而是AOP代理。在執行代理對象的方法以前,能夠經過調用補充方法來進一步「修飾」代理對象(其實所謂的靜態代理不過是在裝飾模式上加了個要不要你來幹動做行爲而已,而不是裝飾模式什麼也不作就加了件衣服,其餘還得由你來全權完成)。

觀察者(Observer)

定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並被自動更新。spring中Observer模式經常使用的地方是listener的實現。如ApplicationListener

補充面試題:Spring裏面的工廠模式和代理模式,IO中的裝飾者模式,挑幾個最熟的能講講思路和僞代碼實現?

16. Spring 的優勢有哪些

  1. 下降了組件之間的耦合性 ,實現了軟件各層之間的解耦
  2. 可使用容易提供的衆多服務,如事務管理,消息服務等
  3. 容器提供單例模式支持
  4. 容器提供了AOP技術,利用它很容易實現如權限攔截,運行期監控等功能
  5. 容器提供了衆多的輔助類,能加快應用的開發
  6. spring對於主流的應用框架提供了集成支持,如hibernate,JPA,Struts等
  7. spring屬於低侵入式設計,代碼的污染極低
  8. 獨立於各類應用服務器
  9. spring的DI機制下降了業務對象替換的複雜性
  10. Spring的高度開放性,並不強制應用徹底依賴於Spring,開發者能夠自由選擇spring的部分或所有

17. IOC和AOP用到的設計模式

用過spring的朋友都知道spring的強大和高深,都以爲深不可測,其實當你真正花些時間讀一讀源碼就知道它的一些技術實現實際上是創建在一些最基本的技術之上而已;例如AOP(面向方面編程)的實現是創建在CGLib提供的類代理和jdk提供的接口代理,IOC(控制反轉)的實現創建在工廠模式、Java反射機制和jdk的操做XML的DOM解析方式.

2、SpringMVC

1. Spring MVC的工做原理

Spring MVC 的工做原理以下圖: 

img

  • ① 客戶端的全部請求都交給前端控制器DispatcherServlet來處理,它會負責調用系統的其餘模塊來真正處理用戶的請求。 
  • ② DispatcherServlet收到請求後,將根據請求的信息(包括URL、HTTP協議方法、請求頭、請求參數、Cookie等)以及HandlerMapping的配置找處處理該請求的Handler(任何一個對象均可以做爲請求的Handler)。 
  • ③ 在這個地方Spring會經過HandlerAdapter對該處理進行封裝。 
  • ④ HandlerAdapter是一個適配器,它用統一的接口對各類Handler中的方法進行調用。 
  • ⑤ Handler完成對用戶請求的處理後,會返回一個ModelAndView對象給DispatcherServlet,ModelAndView顧名思義,包含了數據模型以及相應的視圖的信息。 
  • ⑥ ModelAndView的視圖是邏輯視圖,DispatcherServlet還要藉助ViewResolver完成從邏輯視圖到真實視圖對象的解析工做。 
  • ⑦ 當獲得真正的視圖對象後,DispatcherServlet會利用視圖對象對模型數據進行渲染。 
  • ⑧ 客戶端獲得響應,多是一個普通的HTML頁面,也能夠是XML或JSON字符串,還能夠是一張圖片或者一個PDF文件。

組件及其做用

  1. 前端控制器 (DispatcherServlet)

    接收請求,響應結果,至關於轉發器,中央處理器。負責調用系統的其餘模塊來真正處理用戶的請求。 

    有了DispatcherServlet減小了其餘組件之間的耦合度

  2. 處理器映射器 (HandlerMapping)

    做用:根據請求的 url 查找 Handler

  3. 處理器 (Handler)

    注意:編寫 Handler 時按照 HandlerAdapter 的要求去作,這樣適配器才能夠去正確執行 Handler

  4. 處理器適配器 (HandlerAdapter)

    做用:按照特定規則(HandlerAdapter要求的規則)執行Handler。

  5. 視圖解析器 (ViewResolver)

    做用:進行視圖解析,根據邏輯視圖解析成真正的視圖 (View)

  6. 視圖 (View)

    View 是一個接口實現類支持不一樣的 View 類型(jsp,pdf等等)

注意:只須要程序員開發,處理器和視圖。

2. Spring MVC註解的優勢

3、Hibernate

1. 簡述Hibernate常見優化策略。

  • 制定合理的緩存策略(二級緩存、查詢緩存)。 
  • 採用合理的Session管理機制。 
  • 儘可能使用延遲加載特性。 
  • 設定合理的批處理參數。 
  • 若是能夠,選用UUID做爲主鍵生成器。 
  • 若是能夠,選用基於版本號的樂觀鎖替代悲觀鎖。 
  • 在開發過程當中, 開啓hibernate.show_sql選項查看生成的SQL,從而瞭解底層的情況;開發完成後關閉此選項。 
  • 考慮數據庫自己的優化,合理的索引、恰當的數據分區策略等都會對持久層的性能帶來可觀的提高,但這些須要專業的DBA(數據庫管理員)提供支持。

2. Hibernate一級緩存與二級緩存之間的區別

  • Hibernate的Session提供了一級緩存的功能,默認老是有效的,當應用程序保存持久化實體、修改持久化實體時,Session並不會當即把這種改變提交到數據庫,而是緩存在當前的Session中,除非顯示調用了Session的flush()方法或經過close()方法關閉Session。經過一級緩存,能夠減小程序與數據庫的交互,從而提升數據庫訪問性能。 
  • SessionFactory級別的二級緩存是全局性的,全部的Session能夠共享這個二級緩存。不過二級緩存默認是關閉的,須要顯示開啓並指定須要使用哪一種二級緩存實現類(可使用第三方提供的實現)。一旦開啓了二級緩存並設置了須要使用二級緩存的實體類,SessionFactory就會緩存訪問過的該實體類的每一個對象,除非緩存的數據超出了指定的緩存空間。 
  • 一級緩存和二級緩存都是對整個實體進行緩存,不會緩存普通屬性,若是但願對普通屬性進行緩存,可使用查詢緩存。查詢緩存是將HQL或SQL語句以及它們的查詢結果做爲鍵值對進行緩存,對於一樣的查詢能夠直接從緩存中獲取數據。查詢緩存默認也是關閉的,須要顯示開啓。

3. Hibernate的理解

4、MyBatis

1. Mybatis原理

2. Hibernate瞭解嗎,Mybatis和Hibernate的區別

5、Tomcat

1. tomcat加載基本流程,涉及到的參數

附錄:參考資料

參考資料:

參考面經:

相關文章
相關標籤/搜索