Java 面試知識點解析(七)——Web篇

 
 
  • 前言:

在遨遊了一番 Java Web 的世界以後,發現了本身的一些缺失,因此就着一篇深度好文:知名互聯網公司校招 Java 開發崗面試知識點解析 ,來好好的對 Java 知識點進行復習和學習一番,大部份內容參照自這一篇文章,有一些本身補充的,也算是從新學習一下 Java 吧。javascript

前序文章連接:html

Java 面試知識點解析(一)——基礎知識篇前端

Java 面試知識點解析(二)——高併發編程篇java

Java 面試知識點解析(三)——JVM篇web

Java 面試知識點解析(四)——版本特性篇面試

Java 面試知識點解析(五)——網絡協議篇算法

Java 面試知識點解析(六)——數據庫篇spring


(一)J2EE 相關知識點

不涉及任何框架,對 J2EE 相關知識點的解析sql

1)Servlet 的生命週期?

在 Web 容器中,Servlet 主要經歷 4 個階段,以下圖:數據庫

 
 

1. 加載 Servlet:當 Tomcat 第一次訪問 Servlet 的時候,Tomcat 會負責建立 Servlet 的實例。

2. 初始化 Servlet:當 Servlet 被實例化以後,Tomcat 會調用 init() 方法來初始化這個對象。

3. 處理服務:當瀏覽器訪問 Servlet 的時候,Servlet 會調用 service() 方法處理請求。

4. 銷燬:當 Tomcat 關閉或者檢測到 Servlet 要從 Tomcat 刪除的時候,會自動調用 destroy() 方法,讓該實例所佔用的資源釋放掉。一個 Servlet 若是長時間不被使用的話,也會被 Tomcat 自動銷燬。

  • 簡單總結:只要訪問 Servlet ,就會調用其對應的 service() 方法,init() 方法只會在第一次訪問 Serlvet 的時候纔會被調用。

2)Servlet 的請求流程?

  1. 瀏覽器發出請求: http://localhost:80/xxx1/xxx2 (80端口能夠默認不寫,由於這是http協議默認的端口,平時咱們訪問https://www.baidu.com/ 時其實訪問的是https://www.baidu.com:80/

  2. 服務器解析請求信息:

    • http:協議名稱
    • localhost:訪問的是互聯網中的哪一臺計算機
    • 80:從主機當中找到對應 80 端口的程序 這裏即爲 Tomcat 服務器
    • /xxx1:當前項目的上下文路徑 (即在 server.xml 中配置主機時配置的 path屬性
    • /xxx2:當前請求的資源名
  3. 解析 Tomcat 服務器根目錄下的 /config/server.xml 文件:
    <Context docBase="D:\javaPros\test\webapp" path="xxx1" />
    判斷哪個<Context />元素的 path屬性 屬性爲 xxx1

    • 若找不到,則返回 404錯誤
    • 若找到了,則解析該<Context />元素,獲得docBase屬性,獲取當前訪問 Web 項目的跟的絕對路徑:D:\javaPros\test\webapp
  4. D:\javaPros\test\webapp下的 WEB-INF 下找到 web.xml 文件
    判斷 web.xml 文件中是否有 <url-pattern> 的文本內容爲 /xxx2

    • 若找不到,則返回 404錯誤
    • 若找到了,則繼續獲取該資源對應 Servlet 類的全限名稱: xxx.xxx
  5. 判斷 Servlet 實例緩存池 中是否有 xxx.xxx 的對象

Map<String,Servlet> cache = ......(Tomcat提供的);
    key:存Servlet類的全限定名稱
    value:該Servlet類的對象.
Servlet obj = cache.get("xxx.xxx"); if(obj==null){ //Servlet實例緩存中沒有該類的對象,第一次. GOTO 6: }else{ //有對象,非第一次. GOTO 8: } } 
  1. 使用反射調用構造器,建立對應的對象
    obj = Class.forName("xxx.xxx").newInstance();
    把當前建立的 Servlet 對象,存放在緩存之中,供給下一次的使用.
    cache.put("xxx.xxx",obj);

  2. 建立 ServletConfig 對象,並調用 init() 方法
    obj.init(config);

  3. 建立 ServletRequest 對象和 ServletResponse 對象,並調用 service()方法
    obj.service(req,resp);

  4. service() 方法中對瀏覽器做出響應操做。


3)Servlet 是單例的嗎?爲何?

Servlet 是單例的,瀏覽器屢次對Servlet的請求,通常狀況下,服務器只建立一個Servlet對象,也就是說,Servlet對象一旦建立了,就會駐留在內存中,爲後續的請求作服務,直到服務器關閉。


4)GET 和 POST 的區別

要知道,GET 和 POST 都是請求方式

1. GET:

瀏覽器器地址欄:http://localhost/test.html?name=wmyskxz&sex=male

這裏提交了兩個參數,一個是name屬性值爲wmyskxz,另外一個是sex屬性值爲male,這是一種直接的請求方式,在請求資源後面跟上 ? 符號與參數鏈接,其餘的參數使用 & 符號鏈接。

  • 缺點:
    1.暴露請求信息,不安全
    2.請求信息不能超過1kb,可傳輸的信息有限,不能上傳圖片

2. POST:

瀏覽器地址欄:http://localhost/test.html#

  • 優勢:
    1.隱藏了請求信息,較安全(但仍能夠經過相關工具訪問到數據)
    2.POST 方式沒有限制請求的數據大小,能夠作圖片的上傳

5)Tomcat 中如何解決中文亂碼問題?

Tomcat 服務器中,接受請求的時候,默認的編碼方式爲 ISO-8859-1,而該編碼方式只佔一個字節,不支持中文(兩個字節),因此當咱們作請求的時候,會出現亂碼的問題

解決方案:

1.對亂碼使用 ISO-8859-1 解碼,轉換成byte數組,恢復爲二進制
byte[] data = name.getBytes("ISO-8859-1");

2.對byte數組從新進行 UTF-8 編碼:
name = new String(data,"UTF-8");
可是這樣會出現一個問題,那就是當表單數據太多的時候,這樣反覆解碼-編碼,會很繁瑣。

終極解決方案:

1.對於 POST 請求:
設置請求的編碼方式:request.setCharacterEncoding("UTF-8");
注意:必須在獲取第一個參數以前設置,而且該方式只對 POST 方式有效。

2.對於 GET 請求:
從新設置 Tomcat 的編碼方式,修改 Tomcat 的配置文件:
Tomcat根目錄/conf/server.xml(修改端口的那一行)

 
 

6)forward 與 redirect 的區別

1.請求轉發(forward)

又叫作直接轉發方式,客戶端和瀏覽器只發出一次請求,Servlet、HTML、JSP或其它信息資源,由第二個信息資源響應該請求,在請求對象request中,保存的對象對於每一個信息資源是共享的。

好比:從 AServlet 請求轉發到 BServlet

 
 
  • 語法:
request.getRequestDispatcher(path).forward(request, response);

參數: path,要跳轉到的資源路徑:上下文路徑 / 資源路徑

特色:

1.地址欄中的地址【不會】改變,一般看做是服務端的跳轉

2.只有一個請求

3.資源是共享的

也就是說在兩個 Servlet 中能夠共享請求的資源,能夠經過request.setAttribute(String var1,Object var2)設置要共享的數據資源,並經過request.getAttribute(String var1);獲取傳遞的資源

4.【能夠】訪問 WEB-INF 中的資源

WEB-INF 文件夾是 Java Web 應用的默認安全目錄,即客戶端沒法直接訪問,只有服務端能夠訪問的目錄。若是想在頁面中直接訪問其中的文件,必須經過web.xml文件對要訪問的文件進行相應映射才能訪問。

注意:在實際的開發中,能夠把不但願用戶直接訪問到(經過瀏覽器輸入地址欄)的網頁放在文件夾中經過此方式訪問。

5.請求轉發【不能】跨域訪問

所謂的同域,是指域名,協議,端口均相同

2.URl 重定向(redirect)

又叫作間接轉發方式(Redirect)實際是兩次HTTP請求,服務器端在響應第一次請求的時候,讓瀏覽器再向另一個URL發出請求,從而達到轉發的目的。

好比:從AServlet重定向到BServlet

 
 
  • 語法:
response.sendRedirect(String location);

參數:location,轉發到的資源路徑

特色:

1.地址欄中的地址【會】發生改變,一般看做是客戶端跳轉

2.有兩個請求

3.在兩個 Servlet 中不能夠共享請求中的數據

4.最終的響應由 BServlet 來決定,和 AServlet 沒有關係

5.【不能夠】訪問 WEB-INF 中的資源

6.請求轉發【能】跨域訪問

就像是在網頁中點開了新的連接同樣

  • 總結:URL 重定向至關因而將重定向的資源路徑,從新複製到瀏覽器地址欄中按下回車同樣,從新發送一次新的請求。

7)JSP 的執行原理?

當訪問一個 JSP 頁面時,該頁面請求將會講給服務器中的 JSP 引擎去處理,它負責解釋和執行 JSP 頁面,每一個 JSP 頁面在第一次被訪問時,JSP 引擎就會將它翻譯成一個繼承自 org.apache.jasper.runtime.HttpJspBase類的 Servlet 源程序,接着再編譯成 class 類文件,再由 Web 容器像調用普通 Servlet 程序同樣的方式來裝載和解釋執行這個由 JSP 頁面翻譯成的 Servlet 程序。


8)request.getAttribute() 和 request.getParameter() 有何區別?

  1. request.getParameter() 一般用來接收接收表單的get或者post提交過來的參數;而request.getAttribute()通常和setAttribute()搭配使用,只有先set以後才能經過get方法獲取到Object類型的數據

  2. getAttribute 返回的是對象,而getParameter 返回的是字符串

  3. getAttribute 和 setAttribute 只是在 web 容器內流轉,僅僅是請求處理階段;而 getParameter 取到的數據是經過容器來獲取的。


9)JSP 與 Servlet 的區別?

  1. JSP 實質上就是一個 Servlet。能夠理解爲,JSP 是編譯後的 「Servlet 類」;
  2. JSP 由 HTML 代碼和 JSP 標籤組成,更擅長頁面顯示;而 Servlet 更擅長流程控制;
  3. JSP 感受像是 HTML 中嵌入 Java 代碼,而 Servlet 有些像 Java 中嵌入 HTML 代碼的意思。

10)JSP 靜態包含和動態包含的區別?

(1)靜態包含:編譯指令包含

<%@include file="被包含的頁面的路徑"%>

包含的時機:在 JSP 文件被翻譯的時候合併在一塊兒,最終翻譯獲得一個 class文件

(2)動態包含:動做指令包含

<jsp:include page="被包含頁面的路徑"></jsp:include>

包含的時機:在運行階段合併代碼,最終獲得兩個 class 文件

(3)動態包含和靜態包含的選擇:

  • 若是被包含的頁面若是是靜態頁面,那麼使用靜態包含;
  • 若是被包含的若是是動態頁面,那麼使用動態包含。

11)JSP 有哪些內置對象?做用分別是什麼?

JSP 共有如下 9 個內置的對象:

  1. request:用戶端請求,此請求會包含來自 GET/POST 請求的參數;
  2. response:表示一次響應對象;
  3. pageContext:表示當前的 JSP 對象;
  4. session:表示一次會話對象;
  5. application:表示當前應用對象;
  6. out:表示一個輸出流對象;
  7. config:表示當前 JSP 的配置對象;
  8. page:表示當前頁面;
  9. exception:表示異常對象。

12)JSTL 是什麼?優勢有哪些?

JSTL(JSP StandardTagLibrary,JSP標準標籤庫)是一個不斷完善的開放源代碼的JSP標籤庫,由四個定製標記庫(core、format、xml和sql)和一對通用標記庫驗證器(ScriptFreeTLV和PermittedTaglibsTLV)組成。優勢有:

  1. 在應用程序服務器之間提供了一致的接口,最大程序地提升了WEB應用在各應用服務器之間的移植。

  2. 簡化了JSP和WEB應用程序的開發。

  3. 以一種統一的方式減小了JSP中的scriptlet代碼數量,能夠達到沒有任何scriptlet代碼的程序。在咱們公司的項目中是不容許有任何的scriptlet代碼出如今JSP中。

  4. 容許JSP設計工具與WEB應用程序開發的進一步集成。相信不久就會有支持JSTL的IDE開發工具出現。


13)什麼是 Cookie?Session 和 Cookie 有什麼區別?

Cookie 技術

Cookie 是一種會話技術,用於將用戶的信息保存在客戶端上。Cookie 英文直接翻譯過來就是小甜品,Cookie 的做用呢,通俗的說就是當一個用戶經過 HTTP 訪問一個服務器時,這個服務器會將一些 Key/Value 鍵值對返回給客戶端瀏覽器,並給這些數據加上一些限制條件,在條件符合時這個用戶下次訪問這個服務器時,數據又被完整地帶回給服務器。

這個做用就像是你去超市購物時,第一次給你辦了一張購物卡,在這個購物卡里存放了一些你的我的信息,下次你再來這個超市的時候,你就只須要帶上你的購物卡,直接購物就行了。

 
 

Session 技術

Session:會話,從瀏覽器打開開始,直到瀏覽器關閉結束,不管在這個網站中訪問了多少頁面,點擊了多少連接,都屬於同一個會話。Session 也能夠稱爲會話 Cookie

  • 特色:服務端技術,將數據保存在服務器
 
 

Cookie 與 Session 的區別

  • Cookie 的數據是存放在客戶的瀏覽器上,Session 數據放在服務器上;
  • Cookie 不是很安全,別人能夠分析存放在本地的 Cookie 並進行 Cookie 欺騙,若是考慮安全問題則應當使用 Session;
  • Session 會在必定時間內保存在服務器上,當訪問增多,會比較佔用服務器的資源,因此若是考慮性能問題,則應當使用 Cookie;
  • 單個 Cookie 在客戶端的限制是 3k ,就是說一個站點在客戶端存放的 Cookie 不能超過 3k。

總結: 將登陸信息等重要信息存放爲 Session;其餘信息若是須要保留,能夠存放在 Cookie 中。


14)什麼是過濾器?

過濾器就是 Servlet 的高級特性之一,就是一個具備攔截/過濾功能的一個東西,在生活中過濾器能夠是香菸濾嘴,濾紙,淨水器,空氣淨化器等,在 Web 中僅僅是一個實現了 Filter 接口的 Java 類而已。

  • 特色:雙向,攔截請求,攔截響應
 
 
  • 做用:
    過濾器能夠對全部的請求或者響應作攔截操做

15)爲何在 Web 開發中須要用到過濾器?

  • 問題:爲何非得使用過濾器,我直接在 Servlet 中做判斷不行嗎?
  • 開發遵循的原則:
    1.DRY原則(Don't Reeat Yourself,不要重複你本身):重複,意味着維護的成本很高。
    2.責任分離原則:誰擅長什麼功能就作什麼功能,Servlet 擅長的是邏輯而不是處理請求

舉一個實際的例子:(處理 POST 請求中文編碼的問題)

 
 
  • Web 中過濾器的做用:
    1.能夠在請求資源以前設置請求的編碼
    2.能夠進行登陸校驗
    3.能夠進行請求參數的內容的過濾
    4.數據壓縮 / 數據加密 / 數據格式的轉換
    5.能夠設置瀏覽器相關的數據

16)MVC 模式?

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中也不會充斥着大量的業務代碼。這大大提升了代碼的可讀性和可維護性。


(二)框架相關知識

因爲我沒有接觸和學習過 Hibernate 和 Struts 這兩個框架,因此細節方面的東西請讀者自行收集...

1)什麼是框架?

框架是指完成必定功能的半成品。

框架可以幫助咱們完成的是:項目的總體框架、一些基礎功能、規定了類和對象如何建立,如何協做等,當咱們開發一個項目時,框架幫助咱們完成了一部分功能,咱們本身再完成一部分,那這個項目就完成了。


2)什麼是 Spring ?

  1. Spring 是一個輕量級的 DI / IoC 和 AOP 容器的開源框架,來源於 Rod Johnson 在其著做《Expert one on one J2EE design and development》中闡述的部分理念和原型衍生而來。

  2. Spring 提倡以 「最少侵入」 的方式來管理應用中的代碼,這意味着咱們能夠隨時安裝或者卸載 Spring

  • 適用範圍:任何 Java 應用
  • Spring 的根本使命:簡化 Java 開發

3)什麼是非侵入式設計?

從框架的角度能夠理解爲:無需繼承框架提供的任何類
這樣咱們在更換框架時,以前寫過的代碼幾乎能夠繼續使用。


4)Spring 有什麼優點?

  • 低侵入 / 低耦合 (下降組件之間的耦合度,實現軟件各層之間的解耦)
  • 聲明式事務管理(基於切面和慣例)
  • 方便集成其餘框架(如MyBatis、Hibernate)
  • 下降 Java 開發難度
  • Spring 框架中包括了 J2EE 三層的每一層的解決方案(一站式)

Spring 的框架結構

 
 
  • Data Access/Integration層包含有JDBC、ORM、OXM、JMS和Transaction模塊。
  • Web層包含了Web、Web-Servlet、WebSocket、Web-Porlet模塊。
  • AOP模塊提供了一個符合AOP聯盟標準的面向切面編程的實現。
  • Core Container(核心容器):包含有Beans、Core、Context和SpEL模塊。
  • Test模塊支持使用JUnit和TestNG對Spring組件進行測試。

5)Spring IoC 和 DI 分別是什麼?

Spring IoC

IoC:Inverse of Control(控制反轉),讀做 「反轉控制」,更好理解,不是什麼技術,而是一種設計思想,就是將本來在程序中手動建立對象的控制權,交由Spring框架來管理。

  • 正控:若要使用某個對象,須要本身去負責對象的建立
  • 反控:若要使用某個對象,只須要從 Spring 容器中獲取須要使用的對象,不關心對象的建立過程,也就是把建立對象的控制權反轉給了Spring框架
  • 好萊塢法則:Don’t call me ,I’ll call you

爲了便於理解咱們這裏舉一個鮮明的例子:

在現實生活中,人們要用到同樣東西的時候,第一反應就是去找到這件東西,好比想喝新鮮橙汁,在沒有飲品店的日子裏,最直觀的作法就是:買果汁機、買橙子,而後準備開水。值得注意的是:這些都是你本身「主動」創造的過程,也就是說一杯橙汁須要你本身創造。

 
 

然而到了今時今日,因爲飲品店的盛行,當咱們想喝橙汁時,第一想法就轉換成了找到飲品店的聯繫方式,經過電話等渠道描述你的須要、地址、聯繫方式等,下訂單等待,過一下子就會有人送來橙汁了。

 
 

請注意你並無「主動」去創造橙汁,橙汁是由飲品店創造的,而不是你,然而也徹底達到了你的要求,甚至比你創造的要好上那麼一些。

  • 總結: 這就是一種控制反轉的理念,上述的例子已經很好的說明了問題,咱們再來描述一下控制反轉的概念:控制反轉是一種經過描述(在 Java 中能夠是 XML 或者註解)並經過第三方(Spring)去產生或獲取特定對象的方式。
  • 好處: ① 下降對象之間的耦合;② 咱們不須要理解一個類的具體實現,只須要知道它有什麼用就行了(直接向 IoC 容器拿)

DI:Dependency Injection(依賴注入)

指 Spring 建立對象的過程當中,將對象依賴屬性(簡單值,集合,對象)經過配置設值給該對象

二者的區別

IoC 和 DI 實際上是同一個概念的不一樣角度描述,DI 相對 IoC 而言,明確描述了 「被注入對象依賴 IoC 容器配置依賴對象」

你也能夠簡單的理解爲:IoC 是目的,是一種思想,而 DI 是手段,是一種設計模式。


6)BeanFactory 和 ApplicationContext 的區別

1.BeanFactory:

是Spring中最底層的接口,只提供了最簡單的IoC功能,負責配置,建立和管理bean。在應用中,通常不使用 BeanFactory,而推薦使ApplicationContext(應用上下文),緣由以下。

2.ApplicationContext:

⑴. 繼承了 BeanFactory,擁有了基本的 IoC 功能;
⑵. 除此以外,ApplicationContext 還提供瞭如下功能:
① 支持國際化;② 支持消息機制;③ 支持統一的資源加載;④ 支持AOP功能;

  • 注意: ApplicationContext 和 BeanFactory 相比,最主要的區別在於 BeanFactory 是延遲加載,舉個例子:若是 Bean 沒有徹底注入,BeanFactory 加載後,會在你第一次調用 getBean 方法纔會拋出異常;而 ApplicationContext 會在初始化的時候就加載而且檢查,這樣的好處是能夠及時檢查依賴是否徹底注入;因此一般咱們會選擇 ApplicationContext。

7)IoC 是如何實現的

最後咱們簡單說說IoC是如何實現的。想象一下若是咱們本身來實現這個依賴注入的功能,咱們怎麼來作? 無外乎:

  1. 讀取標註或者配置文件,看看JuiceMaker依賴的是哪一個Source,拿到類名
  2. 使用反射的API,基於類名實例化對應的對象實例
  3. 將對象實例,經過構造函數或者 setter,傳遞給 JuiceMaker

咱們發現其實本身來實現也不是很難,Spring實際也就是這麼作的。這麼看的話其實IoC就是一個工廠模式的升級版!固然要作一個成熟的IoC框架,仍是很是多細緻的工做要作,Spring不只提供了一個已經成爲業界標準的Java IoC框架,還提供了更多強大的功能,因此你們就別去造輪子啦!但願瞭解IoC更多實現細節不妨經過學習Spring的源碼來加深理解!

引用地址:這裏


8)Spring 配置 Bean 有幾種方式?

在 Spring 中提供了 3 種方法進行配置:

  • 在 XML 文件中顯式配置
  • 在 Java 的接口和類中實現配置
  • 隱式 Bean 的發現機制和自動裝配原則

方式選擇的原則

在現實的工做中,這 3 種方式都會被用到,而且在學習和工做之中經常混合使用,因此這裏給出一些關於這 3 種優先級的建議:

1.最優先:經過隱式 Bean 的發現機制和自動裝配的原則。
基於約定因爲配置的原則,這種方式應該是最優先的

  • 好處:減小程序開發者的決定權,簡單又不失靈活。

2.其次:Java 接口和類中配置實現配置
在沒有辦法使用自動裝配原則的狀況下應該優先考慮此類方法

  • 好處:避免 XML 配置的泛濫,也更爲容易。
  • 典型場景:一個父類有多個子類,好比學生類有兩個子類,一個男學生類和女學生類,經過 IoC 容器初始化一個學生類,容器將沒法知道使用哪一個子類去初始化,這個時候可使用 Java 的註解配置去指定。

3.最後:XML 方式配置
在上述方法都沒法使用的狀況下,那麼也只能選擇 XML 配置的方式。

  • 好處:簡單易懂(固然,特別是對於初學者)
  • 典型場景:當使用第三方類的時候,有些類並非咱們開發的,咱們沒法修改裏面的代碼,這個時候就經過 XML 的方式配置使用了。

9)介紹一下 Spring AOP

AOP 即 Aspect Oriented Program 面向切面編程

首先,在面向切面編程的思想裏面,把功能分爲核心業務功能,和周邊功能。

  • 所謂的核心業務,好比登錄,增長數據,刪除數據都叫核心業務
  • 所謂的周邊功能,好比性能統計,日誌,事務管理等等

周邊功能在 Spring 的面向切面編程AOP思想裏,即被定義爲切面

在面向切面編程AOP的思想裏面,核心業務功能和切面功能分別獨立進行開發,而後把切面功能和核心業務功能 "編織" 在一塊兒,這就叫 AOP

仍是來舉一個鮮明的例子:

 
 

在上面的例子中,包租婆的核心業務就是籤合同,收房租,那麼這就夠了,灰色框起來的部分都是重複且邊緣的事,交給中介商就行了,這就是 AOP 的一個思想:讓關注點代碼與業務代碼分離!


10)Spring 中 Bean 的做用域

在默認的狀況下,Spring IoC 容器只會對一個 Bean 建立一個實例,但有時候,咱們但願可以經過 Spring IoC 容器獲取多個實例,咱們能夠經過 @Scope 註解或者 <bean> 元素中的 scope 屬性來設置,例如:

// XML 中設置做用域 <bean id="" class="" scope="prototype" /> // 使用註解設置做用域 @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) 

Spring 提供了 5 種做用域,它會根據狀況來決定是否生成新的對象:

做用域類別 描述
singleton(單例) 在Spring IoC容器中僅存在一個Bean實例 (默認的scope)
prototype(多例) 每次從容器中調用Bean時,都返回一個新的實例,即每次調用getBean()時 ,至關於執行new XxxBean():不會在容器啓動時建立對象
request(請求) 用於web開發,將Bean放入request範圍 ,request.setAttribute("xxx") , 在同一個request 得到同一個Bean
session(會話) 用於web開發,將Bean 放入Session範圍,在同一個Session 得到同一個Bean
globalSession(全局會話) 通常用於 Porlet 應用環境 , 分佈式系統存在全局 session 概念(單點登陸),若是不是 porlet 環境,globalSession 等同於 Session

在開發中主要使用 scope="singleton"scope="prototype"對於MVC中的Action使用prototype類型,其餘使用singleton,Spring容器會管理 Action 對象的建立,此時把 Action 的做用域設置爲 prototype.

擴展閱讀:@Profile 註解條件化裝配 Bean


11)Spring 面試問答 Top 25

更多戳這裏:Spring面試問答Top 25


12)Spring MVC 的請求流程

每當用戶在 Web 瀏覽器中點擊連接或者提交表單的時候,請求就開始工做了,像是郵遞員同樣,從離開瀏覽器開始到獲取響應返回,它會經歷不少站點,在每個站點都會留下一些信息同時也會帶上其餘信息,下圖爲 Spring MVC 的請求流程:

 
 

第一站:DispatcherServlet

從請求離開瀏覽器之後,第一站到達的就是 DispatcherServlet,看名字這是一個 Servlet,經過 J2EE 的學習,咱們知道 Servlet 能夠攔截並處理 HTTP 請求,DispatcherServlet 會攔截全部的請求,而且將這些請求發送給 Spring MVC 控制器。

<servlet> <servlet-name>dispatcher</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>dispatcher</servlet-name> <!-- 攔截全部的請求 --> <url-pattern>/</url-pattern> </servlet-mapping> 
  • DispatcherServlet 的任務就是攔截請求發送給 Spring MVC 控制器。

第二站:處理器映射(HandlerMapping)

  • 問題:典型的應用程序中可能會有多個控制器,這些請求到底應該發給哪個控制器呢?

因此 DispatcherServlet 會查詢一個或多個處理器映射來肯定請求的下一站在哪裏,處理器映射會根據請求所攜帶的 URL 信息來進行決策,例如上面的例子中,咱們經過配置 simpleUrlHandlerMapping 來將 /hello 地址交給 helloController 處理:

<bean id="simpleUrlHandlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping"> <property name="mappings"> <props> <!-- /hello 路徑的請求交給 id 爲 helloController 的控制器處理--> <prop key="/hello">helloController</prop> </props> </property> </bean> <bean id="helloController" class="controller.HelloController"></bean> 

第三站:控制器

一旦選擇了合適的控制器, DispatcherServlet 會將請求發送給選中的控制器,到了控制器,請求會卸下其負載(用戶提交的請求)等待控制器處理完這些信息:

public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception { // 處理邏輯 .... } 

第四站:返回 DispatcherServlet

當控制器在完成邏輯處理後,一般會產生一些信息,這些信息就是須要返回給用戶並在瀏覽器上顯示的信息,它們被稱爲模型(Model)。僅僅返回原始的信息時不夠的——這些信息須要以用戶友好的方式進行格式化,通常會是 HTML,因此,信息須要發送給一個視圖(view),一般會是 JSP。

控制器所作的最後一件事就是將模型數據打包,而且表示出用於渲染輸出的視圖名(邏輯視圖名)。它接下來會將請求連同模型和視圖名發送回 DispatcherServlet。

public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception { // 處理邏輯 .... // 返回給 DispatcherServlet return mav; } 

第五站:視圖解析器

這樣以來,控制器就不會和特定的視圖相耦合,傳遞給 DispatcherServlet 的視圖名並不直接表示某個特定的 JSP。(實際上,它甚至不能肯定視圖就是 JSP)相反,它傳遞的僅僅是一個邏輯名稱,這個名稱將會用來查找產生結果的真正視圖。

DispatcherServlet 將會使用視圖解析器(view resolver)來將邏輯視圖名匹配爲一個特定的視圖實現,它多是也可能不是 JSP

上面的例子是直接綁定到了 index.jsp 視圖

第六站:視圖

既然 DispatcherServlet 已經知道由哪一個視圖渲染結果了,那請求的任務基本上也就完成了。

它的最後一站是視圖的實現,在這裏它交付模型數據,請求的任務也就完成了。視圖使用模型數據渲染出結果,這個輸出結果會經過響應對象傳遞給客戶端。

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false"%> <h1>${message}</h1> 

更多 Spring-MVC 內容:Spring MVC【入門】就這一篇


13)什麼是 ORM?

對象關係映射(Object-Relational Mapping,簡稱ORM)是一種爲了解決程序的面向對象模型與數據庫的關係模型互不匹配問題的技術;

簡單的說,ORM是經過使用描述對象和數據庫之間映射的元數據(在Java中能夠用XML或者是註解),將程序中的對象自動持久化到關係數據庫中或者將關係數據庫表中的行轉換成Java對象,其本質上就是將數據從一種形式轉換到另一種形式。


14)爲何要使用 MyBatis ?

在咱們傳統的 JDBC 中,咱們除了須要本身提供 SQL 外,還必須操做 Connection、Statment、ResultSet,不只如此,爲了訪問不一樣的表,不一樣字段的數據,咱們須要些不少雷同模板化的代碼,閒的繁瑣又枯燥。

而咱們在使用了 MyBatis 以後,只須要提供 SQL 語句就行了,其他的諸如:創建鏈接、操做 Statment、ResultSet,處理 JDBC 相關異常等等均可以交給 MyBatis 去處理,咱們的關注點因而能夠就此集中在 SQL 語句上,關注在增刪改查這些操做層面上。

而且 MyBatis 支持使用簡單的 XML 或註解來配置和映射原生信息,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成數據庫中的記錄。


15)MyBatis 中佔位符 #$ 的區別

區別以下:

  1. #符號將傳入的數據都當作一個字符串,會對自動傳入的數據加一個雙引號
  2. $符號將傳入的數據直接顯示生成SQL中。
  3. #符號存在預編譯的過程,,對問號賦值,防止SQL注入。
  4. $符號是直譯的方式,通常用在orderby {列名} 語句中。
  5. 能用#號就不要用$符號

16)MyBatis 緩存結構

 
 

在 Web 系統中,最重要的操做就是查詢數據庫中的數據。可是有些時候查詢數據的頻率很是高,這是很耗費數據庫資源的,每每會致使數據庫查詢效率極低,影響客戶的操做體驗。因而咱們能夠將一些變更不大且訪問頻率高的數據,放置在一個緩存容器中,用戶下一次查詢時就從緩存容器中獲取結果。

  • MyBatis 擁有本身的緩存結構,能夠用來緩解數據庫壓力,加快查詢速度。
  • MyBatis 一級緩存是一個 SqlSession 級別,同一個 SqlSession 只能訪問本身的一級緩存的數據
  • 二級緩存是跨sqlSession,是 mapper 級別的緩存,對於 mapper 級別的緩存不一樣的sqlsession是能夠共享的。

更多深刻MyBatis的內容戳這裏:MyBatis(2)——MyBatis 深刻學習


17)MyBatis 與 Spring 整合

戳這裏:MyBatis 與 Spring 整合


18)IDEA 整合 SSM 框架學習

戳這裏IDEA 整合 SSM 框架學習


19)MVC 三種模式

在早期 Java Web 的開發中,統一把顯示層、控制層、數據層的操做所有交給 JSP 或者 JavaBean 來進行處理,咱們稱之爲 Model1:

 
 
  • 出現的弊端:
  • JSP 和 Java Bean 之間嚴重耦合,Java 代碼和 HTML 代碼也耦合在了一塊兒
  • 要求開發者不只要掌握 Java ,還要有高超的前端水平
  • 前端和後端相互依賴,前端須要等待後端完成,後端也依賴前端完成,才能進行有效的測試
  • 代碼難以複用

正由於上面的種種弊端,因此很快這種方式就被 Servlet + JSP + Java Bean 所替代了,早期的 MVC 模型(Model2)就像下圖這樣:

 
 

首先用戶的請求會到達 Servlet,而後根據請求調用相應的 Java Bean,並把全部的顯示結果交給 JSP 去完成,這樣的模式咱們就稱爲 MVC 模式。

  • M 表明 模型(Model)
    模型是什麼呢? 模型就是數據,就是 dao,bean
  • V 表明 視圖(View)
    視圖是什麼呢? 就是網頁, JSP,用來展現模型中的數據
  • C 表明 控制器(controller)
    控制器是什麼? 控制器的做用就是把不一樣的數據(Model),顯示在不一樣的視圖(View)上,Servlet 扮演的就是這樣的角色。

擴展閱讀:Web開發模式

Spring MVC 的架構

爲解決持久層中一直未處理好的數據庫事務的編程,又爲了迎合 NoSQL 的強勢崛起,Spring MVC 給出了方案:

 
 

傳統的模型層被拆分爲了業務層(Service)和數據訪問層(DAO,Data Access Object)。在 Service 下能夠經過 Spring 的聲明式事務操做數據訪問層,而在業務層上還容許咱們訪問 NoSQL ,這樣就可以知足異軍突起的 NoSQL 的使用了,它能夠大大提升互聯網系統的性能。

  • 特色:
    結構鬆散,幾乎能夠在 Spring MVC 中使用各種視圖
    鬆耦合,各個模塊分離
    與 Spring 無縫集成

20)分頁?

戳這裏:Java Web -【分頁功能】詳解


21)什麼是 Spring Boot ?

  • 它使用 「習慣優於配置」 (項目中存在大量的配置,此外還內置一個習慣性的配置,讓你無須)的理念讓你的項目快速運行起來。
  • 它並非什麼新的框架,而是默認配置了不少框架的使用方式,就像 Maven 整合了全部的 jar 包同樣,Spring Boot 整合了全部框架(引自:springboot(一):入門篇——純潔的微笑

22)使用 Spring Boot 有什麼好處?

回顧咱們以前的 SSM 項目,搭建過程仍是比較繁瑣的,須要:

  • 1)配置 web.xml,加載 spring 和 spring mvc
  • 2)配置數據庫鏈接、配置日誌文件
  • 3)配置家在配置文件的讀取,開啓註解
  • 4)配置mapper文件
  • .....

而使用 Spring Boot 來開發項目則只須要很是少的幾個配置就能夠搭建起來一個 Web 項目,而且利用 IDEA 能夠自動生成生成,這簡直是太爽了...

  • 劃重點:簡單、快速、方便地搭建項目;對主流開發框架的無配置集成;極大提升了開發、部署效率。

Spring Boot 因爲筆者尚未深刻學習..因此細節部分請讀者自行收集...


歡迎轉載,轉載請註明出處!轉載自@我沒有三顆心臟

相關文章
相關標籤/搜索