- 前言:
在遨游了一番 Java Web 的世界之后,發(fā)現(xiàn)了自己的一些缺失速兔,所以就著一篇深度好文:知名互聯(lián)網(wǎng)公司校招 Java 開(kāi)發(fā)崗面試知識(shí)點(diǎn)解析 岗钩,來(lái)好好的對(duì) Java 知識(shí)點(diǎn)進(jìn)行復(fù)習(xí)和學(xué)習(xí)一番葡盗,大部分內(nèi)容參照自這一篇文章,有一些自己補(bǔ)充的谈飒,也算是重新學(xué)習(xí)一下 Java 吧。
前序文章鏈接:
Java 面試知識(shí)點(diǎn)解析(一)——基礎(chǔ)知識(shí)篇
Java 面試知識(shí)點(diǎn)解析(二)——高并發(fā)編程篇
Java 面試知識(shí)點(diǎn)解析(三)——JVM篇
Java 面試知識(shí)點(diǎn)解析(四)——版本特性篇
Java 面試知識(shí)點(diǎn)解析(五)——網(wǎng)絡(luò)協(xié)議篇
Java 面試知識(shí)點(diǎn)解析(六)——數(shù)據(jù)庫(kù)篇
(一)J2EE 相關(guān)知識(shí)點(diǎn)
不涉及任何框架态蒂,對(duì) J2EE 相關(guān)知識(shí)點(diǎn)的解析
1)Servlet 的生命周期杭措?
在 Web 容器中,Servlet 主要經(jīng)歷 4 個(gè)階段钾恢,如下圖:
1. 加載 Servlet:當(dāng) Tomcat 第一次訪問(wèn) Servlet 的時(shí)候手素,Tomcat 會(huì)負(fù)責(zé)創(chuàng)建 Servlet 的實(shí)例。
2. 初始化 Servlet:當(dāng) Servlet 被實(shí)例化之后瘩蚪,Tomcat 會(huì)調(diào)用 init() 方法來(lái)初始化這個(gè)對(duì)象泉懦。
3. 處理服務(wù):當(dāng)瀏覽器訪問(wèn) Servlet 的時(shí)候,Servlet 會(huì)調(diào)用 service() 方法處理請(qǐng)求疹瘦。
4. 銷(xiāo)毀:當(dāng) Tomcat 關(guān)閉或者檢測(cè)到 Servlet 要從 Tomcat 刪除的時(shí)候崩哩,會(huì)自動(dòng)調(diào)用 destroy() 方法,讓該實(shí)例所占用的資源釋放掉拱礁。一個(gè) Servlet 如果長(zhǎng)時(shí)間不被使用的話琢锋,也會(huì)被 Tomcat 自動(dòng)銷(xiāo)毀。
- 簡(jiǎn)單總結(jié):只要訪問(wèn) Servlet 呢灶,就會(huì)調(diào)用其對(duì)應(yīng)的 service() 方法吴超,init() 方法只會(huì)在第一次訪問(wèn) Serlvet 的時(shí)候才會(huì)被調(diào)用。
2)Servlet 的請(qǐng)求流程鸯乃?
瀏覽器發(fā)出請(qǐng)求:
http://localhost:80/xxx1/xxx2
(80端口可以默認(rèn)不寫(xiě)鲸阻,因?yàn)檫@是http協(xié)議默認(rèn)的端口,平時(shí)我們?cè)L問(wèn)https://www.baidu.com/
時(shí)其實(shí)訪問(wèn)的是https://www.baidu.com:80/
)-
服務(wù)器解析請(qǐng)求信息:
- http:協(xié)議名稱(chēng)
- localhost:訪問(wèn)的是互聯(lián)網(wǎng)中的哪一臺(tái)計(jì)算機(jī)
- 80:從主機(jī)當(dāng)中找到對(duì)應(yīng) 80 端口的程序 (這里即為 Tomcat 服務(wù)器)
- /xxx1:當(dāng)前項(xiàng)目的上下文路徑 (即在 server.xml 中配置主機(jī)時(shí)配置的 path屬性)
- /xxx2:當(dāng)前請(qǐng)求的資源名
-
解析 Tomcat 服務(wù)器根目錄下的 /config/server.xml 文件:
<Context docBase="D:\javaPros\test\webapp" path="xxx1" />
判斷哪一個(gè)<Context />
元素的 path屬性 屬性為xxx1
- 若找不到缨睡,則返回 404錯(cuò)誤
- 若找到了鸟悴,則解析該
<Context />
元素,得到docBase
屬性奖年,獲取當(dāng)前訪問(wèn) Web 項(xiàng)目的跟的絕對(duì)路徑:D:\javaPros\test\webapp
-
從
D:\javaPros\test\webapp
下的 WEB-INF 下找到 web.xml 文件
判斷 web.xml 文件中是否有<url-pattern>
的文本內(nèi)容為 /xxx2- 若找不到细诸,則返回 404錯(cuò)誤
- 若找到了,則繼續(xù)獲取該資源對(duì)應(yīng) Servlet 類(lèi)的全限名稱(chēng): xxx.xxx
判斷 Servlet 實(shí)例緩存池 中是否有 xxx.xxx 的對(duì)象
Map<String,Servlet> cache = ......(Tomcat提供的);
key:存Servlet類(lèi)的全限定名稱(chēng)
value:該Servlet類(lèi)的對(duì)象.
Servlet obj = cache.get("xxx.xxx");
if(obj==null){
//Servlet實(shí)例緩存中沒(méi)有該類(lèi)的對(duì)象,第一次.
GOTO 6:
}else{
//有對(duì)象,非第一次.
GOTO 8:
}
}
使用反射調(diào)用構(gòu)造器陋守,創(chuàng)建對(duì)應(yīng)的對(duì)象
obj = Class.forName("xxx.xxx").newInstance();
把當(dāng)前創(chuàng)建的 Servlet 對(duì)象震贵,存放在緩存之中利赋,供給下一次的使用.
cache.put("xxx.xxx",obj);
創(chuàng)建 ServletConfig 對(duì)象,并調(diào)用 init() 方法
obj.init(config);
創(chuàng)建 ServletRequest 對(duì)象和 ServletResponse 對(duì)象猩系,并調(diào)用 service()方法
obj.service(req,resp);
在 service() 方法中對(duì)瀏覽器作出響應(yīng)操作媚送。
3)Servlet 是單例的嗎?為什么寇甸?
Servlet 是單例的塘偎,瀏覽器多次對(duì)Servlet的請(qǐng)求,一般情況下拿霉,服務(wù)器只創(chuàng)建一個(gè)Servlet對(duì)象吟秩,也就是說(shuō),Servlet對(duì)象一旦創(chuàng)建了友浸,就會(huì)駐留在內(nèi)存中峰尝,為后續(xù)的請(qǐng)求做服務(wù),直到服務(wù)器關(guān)閉收恢。
4)GET 和 POST 的區(qū)別
要知道武学,GET 和 POST 都是請(qǐng)求方式
1. GET:
瀏覽器器地址欄:http://localhost/test.html?name=wmyskxz&sex=male
這里提交了兩個(gè)參數(shù),一個(gè)是name
屬性值為wmyskxz
伦意,另一個(gè)是sex
屬性值為male
火窒,這是一種直接的請(qǐng)求方式,在請(qǐng)求資源后面跟上 ? 符號(hào)與參數(shù)連接驮肉,其他的參數(shù)使用 & 符號(hào)連接熏矿。
-
缺點(diǎn):
1.暴露請(qǐng)求信息,不安全
2.請(qǐng)求信息不能超過(guò)1kb离钝,可傳輸?shù)男畔⒂邢奁北啵荒苌蟼鲌D片
2. POST:
瀏覽器地址欄:http://localhost/test.html#
-
優(yōu)點(diǎn):
1.隱藏了請(qǐng)求信息,較安全(但仍可以通過(guò)相關(guān)工具訪問(wèn)到數(shù)據(jù))
2.POST 方式沒(méi)有限制請(qǐng)求的數(shù)據(jù)大小卵渴,可以做圖片的上傳
5)Tomcat 中如何解決中文亂碼問(wèn)題慧域?
在 Tomcat 服務(wù)器中,接受請(qǐng)求的時(shí)候浪读,默認(rèn)的編碼方式為 ISO-8859-1昔榴,而該編碼方式只占一個(gè)字節(jié),不支持中文(兩個(gè)字節(jié))碘橘,所以當(dāng)我們做請(qǐng)求的時(shí)候互订,會(huì)出現(xiàn)亂碼的問(wèn)題
解決方案:
1.對(duì)亂碼使用 ISO-8859-1 解碼,轉(zhuǎn)換成byte數(shù)組痘拆,恢復(fù)為二進(jìn)制
byte[] data = name.getBytes("ISO-8859-1");
2.對(duì)byte數(shù)組重新進(jìn)行 UTF-8 編碼:
name = new String(data,"UTF-8");
但是這樣會(huì)出現(xiàn)一個(gè)問(wèn)題仰禽,那就是當(dāng)表單數(shù)據(jù)太多的時(shí)候,這樣反復(fù)解碼-編碼,會(huì)很繁瑣坟瓢。
終極解決方案:
1.對(duì)于 POST 請(qǐng)求:
設(shè)置請(qǐng)求的編碼方式:request.setCharacterEncoding("UTF-8");
注意:必須在獲取第一個(gè)參數(shù)之前設(shè)置勇边,并且該方式只對(duì) POST 方式有效犹撒。
2.對(duì)于 GET 請(qǐng)求:
重新設(shè)置 Tomcat 的編碼方式折联,修改 Tomcat 的配置文件:
Tomcat根目錄/conf/server.xml(修改端口的那一行)
6)forward 與 redirect 的區(qū)別
1.請(qǐng)求轉(zhuǎn)發(fā)(forward)
又叫做直接轉(zhuǎn)發(fā)方式,客戶端和瀏覽器只發(fā)出一次請(qǐng)求识颊,Servlet诚镰、HTML、JSP或其它信息資源祥款,由第二個(gè)信息資源響應(yīng)該請(qǐng)求清笨,在請(qǐng)求對(duì)象request中,保存的對(duì)象對(duì)于每個(gè)信息資源是共享的刃跛。
比如:從 AServlet 請(qǐng)求轉(zhuǎn)發(fā)到 BServlet
- 語(yǔ)法:
request.getRequestDispatcher(path).forward(request, response);
參數(shù): path
抠艾,要跳轉(zhuǎn)到的資源路徑:上下文路徑 / 資源路徑
特點(diǎn):
1.地址欄中的地址【不會(huì)】改變,通辰瓣迹看作是服務(wù)端的跳轉(zhuǎn)
2.只有一個(gè)請(qǐng)求
3.資源是共享的
也就是說(shuō)在兩個(gè) Servlet 中可以共享請(qǐng)求的資源检号,可以通過(guò)request.setAttribute(String var1,Object var2)
設(shè)置要共享的數(shù)據(jù)資源,并通過(guò)request.getAttribute(String var1);
來(lái)獲取傳遞的資源
4.【可以】訪問(wèn) WEB-INF 中的資源
WEB-INF 文件夾是 Java Web 應(yīng)用的默認(rèn)安全目錄蛙酪,即客戶端無(wú)法直接訪問(wèn)齐苛,只有服務(wù)端可以訪問(wèn)的目錄。如果想在頁(yè)面中直接訪問(wèn)其中的文件桂塞,必須通過(guò)web.xml文件對(duì)要訪問(wèn)的文件進(jìn)行相應(yīng)映射才能訪問(wèn)凹蜂。
注意:在實(shí)際的開(kāi)發(fā)中,可以把不希望用戶直接訪問(wèn)到(通過(guò)瀏覽器輸入地址欄)的網(wǎng)頁(yè)放在文件夾中通過(guò)此方式訪問(wèn)阁危。
5.請(qǐng)求轉(zhuǎn)發(fā)【不能】跨域訪問(wèn)
所謂的同域玛痊,是指域名,協(xié)議狂打,端口均相同
2.URl 重定向(redirect)
又叫做間接轉(zhuǎn)發(fā)方式(Redirect)實(shí)際是兩次HTTP請(qǐng)求擂煞,服務(wù)器端在響應(yīng)第一次請(qǐng)求的時(shí)候,讓瀏覽器再向另外一個(gè)URL發(fā)出請(qǐng)求菱父,從而達(dá)到轉(zhuǎn)發(fā)的目的颈娜。
比如:從AServlet重定向到BServlet
- 語(yǔ)法:
response.sendRedirect(String location);
參數(shù):location
,轉(zhuǎn)發(fā)到的資源路徑
特點(diǎn):
1.地址欄中的地址【會(huì)】發(fā)生改變浙宜,通彻倭桑看作是客戶端跳轉(zhuǎn)
2.有兩個(gè)請(qǐng)求
3.在兩個(gè) Servlet 中不可以共享請(qǐng)求中的數(shù)據(jù)
4.最終的響應(yīng)由 BServlet 來(lái)決定,和 AServlet 沒(méi)有關(guān)系
5.【不可以】訪問(wèn) WEB-INF 中的資源
6.請(qǐng)求轉(zhuǎn)發(fā)【能】跨域訪問(wèn)
就像是在網(wǎng)頁(yè)中點(diǎn)開(kāi)了新的鏈接一樣
- 總結(jié):URL 重定向相當(dāng)于是將重定向的資源路徑粟瞬,重新復(fù)制到瀏覽器地址欄中按下回車(chē)一樣同仆,重新發(fā)送一次新的請(qǐng)求。
7)JSP 的執(zhí)行原理裙品?
當(dāng)訪問(wèn)一個(gè) JSP 頁(yè)面時(shí)俗批,該頁(yè)面請(qǐng)求將會(huì)講給服務(wù)器中的 JSP 引擎去處理俗或,它負(fù)責(zé)解釋和執(zhí)行 JSP 頁(yè)面,每個(gè) JSP 頁(yè)面在第一次被訪問(wèn)時(shí)岁忘,JSP 引擎就會(huì)將它翻譯成一個(gè)繼承自 org.apache.jasper.runtime.HttpJspBase
類(lèi)的 Servlet 源程序辛慰,接著再編譯成 class 類(lèi)文件,再由 Web 容器像調(diào)用普通 Servlet 程序一樣的方式來(lái)裝載和解釋執(zhí)行這個(gè)由 JSP 頁(yè)面翻譯成的 Servlet 程序干像。
8)request.getAttribute() 和 request.getParameter() 有何區(qū)別帅腌?
request.getParameter() 通常用來(lái)接收接收表單的get或者post提交過(guò)來(lái)的參數(shù);而request.getAttribute()一般和setAttribute()搭配使用麻汰,只有先set之后才能通過(guò)get方法獲取到Object類(lèi)型的數(shù)據(jù)
getAttribute 返回的是對(duì)象速客,而getParameter 返回的是字符串
getAttribute 和 setAttribute 只是在 web 容器內(nèi)流轉(zhuǎn),僅僅是請(qǐng)求處理階段五鲫;而 getParameter 取到的數(shù)據(jù)是通過(guò)容器來(lái)獲取的溺职。
9)JSP 與 Servlet 的區(qū)別?
- JSP 實(shí)質(zhì)上就是一個(gè) Servlet位喂。可以理解為浪耘,JSP 是編譯后的 “Servlet 類(lèi)”;
- JSP 由 HTML 代碼和 JSP 標(biāo)簽組成忆某,更擅長(zhǎng)頁(yè)面顯示点待;而 Servlet 更擅長(zhǎng)流程控制;
- JSP 感覺(jué)像是 HTML 中嵌入 Java 代碼弃舒,而 Servlet 有些像 Java 中嵌入 HTML 代碼的意思癞埠。
10)JSP 靜態(tài)包含和動(dòng)態(tài)包含的區(qū)別?
(1)靜態(tài)包含:編譯指令包含
<%@include file="被包含的頁(yè)面的路徑"%>
包含的時(shí)機(jī):在 JSP 文件被翻譯的時(shí)候合并在一起聋呢,最終翻譯得到一個(gè) class文件
(2)動(dòng)態(tài)包含:動(dòng)作指令包含
<jsp:include page="被包含頁(yè)面的路徑"></jsp:include>
包含的時(shí)機(jī):在運(yùn)行階段合并代碼苗踪,最終得到兩個(gè) class 文件
(3)動(dòng)態(tài)包含和靜態(tài)包含的選擇:
- 如果被包含的頁(yè)面如果是靜態(tài)頁(yè)面,那么使用靜態(tài)包含;
- 如果被包含的如果是動(dòng)態(tài)頁(yè)面,那么使用動(dòng)態(tài)包含削锰。
11)JSP 有哪些內(nèi)置對(duì)象通铲?作用分別是什么?
JSP 共有以下 9 個(gè)內(nèi)置的對(duì)象:
- request:用戶端請(qǐng)求器贩,此請(qǐng)求會(huì)包含來(lái)自 GET/POST 請(qǐng)求的參數(shù)颅夺;
- response:表示一次響應(yīng)對(duì)象;
- pageContext:表示當(dāng)前的 JSP 對(duì)象蛹稍;
- session:表示一次會(huì)話對(duì)象吧黄;
- application:表示當(dāng)前應(yīng)用對(duì)象;
- out:表示一個(gè)輸出流對(duì)象唆姐;
- config:表示當(dāng)前 JSP 的配置對(duì)象拗慨;
- page:表示當(dāng)前頁(yè)面;
- exception:表示異常對(duì)象。
12)JSTL 是什么赵抢??jī)?yōu)點(diǎn)有哪些剧蹂?
JSTL(JSP StandardTagLibrary,JSP標(biāo)準(zhǔn)標(biāo)簽庫(kù))是一個(gè)不斷完善的開(kāi)放源代碼的JSP標(biāo)簽庫(kù)烦却,由四個(gè)定制標(biāo)記庫(kù)(core宠叼、format、xml和sql)和一對(duì)通用標(biāo)記庫(kù)驗(yàn)證器(ScriptFreeTLV和PermittedTaglibsTLV)組成短绸。優(yōu)點(diǎn)有:
在應(yīng)用程序服務(wù)器之間提供了一致的接口车吹,最大程序地提高了WEB應(yīng)用在各應(yīng)用服務(wù)器之間的移植。
簡(jiǎn)化了JSP和WEB應(yīng)用程序的開(kāi)發(fā)醋闭。
以一種統(tǒng)一的方式減少了JSP中的scriptlet代碼數(shù)量,可以達(dá)到?jīng)]有任何scriptlet代碼的程序朝卒。在我們公司的項(xiàng)目中是不允許有任何的scriptlet代碼出現(xiàn)在JSP中证逻。
允許JSP設(shè)計(jì)工具與WEB應(yīng)用程序開(kāi)發(fā)的進(jìn)一步集成。相信不久就會(huì)有支持JSTL的IDE開(kāi)發(fā)工具出現(xiàn)抗斤。
13)什么是 Cookie囚企?Session 和 Cookie 有什么區(qū)別?
Cookie 技術(shù)
Cookie 是一種會(huì)話技術(shù)瑞眼,用于將用戶的信息保存在客戶端上龙宏。Cookie 英文直接翻譯過(guò)來(lái)就是小甜品,Cookie 的作用呢伤疙,通俗的說(shuō)就是當(dāng)一個(gè)用戶通過(guò) HTTP 訪問(wèn)一個(gè)服務(wù)器時(shí)银酗,這個(gè)服務(wù)器會(huì)將一些 Key/Value 鍵值對(duì)返回給客戶端瀏覽器,并給這些數(shù)據(jù)加上一些限制條件徒像,在條件符合時(shí)這個(gè)用戶下次訪問(wèn)這個(gè)服務(wù)器時(shí)黍特,數(shù)據(jù)又被完整地帶回給服務(wù)器。
這個(gè)作用就像是你去超市購(gòu)物時(shí)锯蛀,第一次給你辦了一張購(gòu)物卡灭衷,在這個(gè)購(gòu)物卡里存放了一些你的個(gè)人信息,下次你再來(lái)這個(gè)超市的時(shí)候旁涤,你就只需要帶上你的購(gòu)物卡翔曲,直接購(gòu)物就好了。
Session 技術(shù)
Session:會(huì)話劈愚,從瀏覽器打開(kāi)開(kāi)始瞳遍,直到瀏覽器關(guān)閉結(jié)束,無(wú)論在這個(gè)網(wǎng)站中訪問(wèn)了多少頁(yè)面造虎,點(diǎn)擊了多少鏈接傅蹂,都屬于同一個(gè)會(huì)話。Session 也可以稱(chēng)為會(huì)話 Cookie
- 特點(diǎn):服務(wù)端技術(shù),將數(shù)據(jù)保存在服務(wù)器
Cookie 與 Session 的區(qū)別
- Cookie 的數(shù)據(jù)是存放在客戶的瀏覽器上份蝴,Session 數(shù)據(jù)放在服務(wù)器上犁功;
- Cookie 不是很安全,別人可以分析存放在本地的 Cookie 并進(jìn)行 Cookie 欺騙婚夫,如果考慮安全問(wèn)題則應(yīng)當(dāng)使用 Session浸卦;
- Session 會(huì)在一定時(shí)間內(nèi)保存在服務(wù)器上,當(dāng)訪問(wèn)增多案糙,會(huì)比較占用服務(wù)器的資源限嫌,所以如果考慮性能問(wèn)題,則應(yīng)當(dāng)使用 Cookie时捌;
- 單個(gè) Cookie 在客戶端的限制是 3k 怒医,就是說(shuō)一個(gè)站點(diǎn)在客戶端存放的 Cookie 不能超過(guò) 3k。
總結(jié): 將登錄信息等重要信息存放為 Session奢讨;其他信息如果需要保留稚叹,可以存放在 Cookie 中。
14)什么是過(guò)濾器拿诸?
過(guò)濾器就是 Servlet 的高級(jí)特性之一扒袖,就是一個(gè)具有攔截/過(guò)濾功能的一個(gè)東西,在生活中過(guò)濾器可以是香煙濾嘴亩码,濾紙季率,凈水器,空氣凈化器等描沟,在 Web 中僅僅是一個(gè)實(shí)現(xiàn)了 Filter 接口的 Java 類(lèi)而已飒泻。
- 特點(diǎn):雙向,攔截請(qǐng)求啊掏,攔截響應(yīng)
-
作用:
過(guò)濾器可以對(duì)所有的請(qǐng)求或者響應(yīng)做攔截操作
15)為什么在 Web 開(kāi)發(fā)中需要用到過(guò)濾器蠢络?
- 問(wèn)題:為什么非得使用過(guò)濾器,我直接在 Servlet 中作判斷不行嗎迟蜜?
-
開(kāi)發(fā)遵循的原則:
1.DRY原則(Don't Reeat Yourself刹孔,不要重復(fù)你自己):重復(fù),意味著維護(hù)的成本很高娜睛。
2.責(zé)任分離原則:誰(shuí)擅長(zhǎng)什么功能就做什么功能髓霞,Servlet 擅長(zhǎng)的是邏輯而不是處理請(qǐng)求
舉一個(gè)實(shí)際的例子:(處理 POST 請(qǐng)求中文編碼的問(wèn)題)
-
Web 中過(guò)濾器的作用:
1.可以在請(qǐng)求資源之前設(shè)置請(qǐng)求的編碼
2.可以進(jìn)行登錄校驗(yàn)
3.可以進(jìn)行請(qǐng)求參數(shù)的內(nèi)容的過(guò)濾
4.數(shù)據(jù)壓縮 / 數(shù)據(jù)加密 / 數(shù)據(jù)格式的轉(zhuǎn)換
5.可以設(shè)置瀏覽器相關(guān)的數(shù)據(jù)
16)MVC 模式?
MVC模式(Model-View-Controller)是軟件工程中的一種軟件架構(gòu)模式畦戒,把軟件系統(tǒng)分為三個(gè)基本部分:模型(Model)方库、視圖(View)和控制器(Controller):
- Controller——負(fù)責(zé)轉(zhuǎn)發(fā)請(qǐng)求,對(duì)請(qǐng)求進(jìn)行處理
- View——負(fù)責(zé)界面顯示
- Model——業(yè)務(wù)功能編寫(xiě)(例如算法實(shí)現(xiàn))障斋、數(shù)據(jù)庫(kù)設(shè)計(jì)以及數(shù)據(jù)存取操作實(shí)現(xiàn)
在JSP/Servlet開(kāi)發(fā)的軟件系統(tǒng)中纵潦,這三個(gè)部分的描述如下所示:
1.Web瀏覽器發(fā)送HTTP請(qǐng)求到服務(wù)端徐鹤,被Controller(Servlet)獲取并進(jìn)行處理(例如參數(shù)解析、請(qǐng)求轉(zhuǎn)發(fā))
2.Controller(Servlet)調(diào)用核心業(yè)務(wù)邏輯——Model部分邀层,獲得結(jié)果
3.Controller(Servlet)將邏輯處理結(jié)果交給View(JSP)返敬,動(dòng)態(tài)輸出HTML內(nèi)容
4.動(dòng)態(tài)生成的HTML內(nèi)容返回到瀏覽器顯示
MVC模式在Web開(kāi)發(fā)中的好處是非常明顯,它規(guī)避了JSP與Servlet各自的短板寥院,Servlet只負(fù)責(zé)業(yè)務(wù)邏輯而不會(huì)通過(guò)out.append()動(dòng)態(tài)生成HTML代碼劲赠;JSP中也不會(huì)充斥著大量的業(yè)務(wù)代碼。這大大提高了代碼的可讀性和可維護(hù)性秸谢。
- 參考:知乎@David
(二)框架相關(guān)知識(shí)
由于我沒(méi)有接觸和學(xué)習(xí)過(guò) Hibernate 和 Struts 這兩個(gè)框架凛澎,所以細(xì)節(jié)方面的東西請(qǐng)讀者自行收集...
1)什么是框架?
框架是指完成一定功能的半成品估蹄。
框架能夠幫助我們完成的是:項(xiàng)目的整體框架塑煎、一些基礎(chǔ)功能、規(guī)定了類(lèi)和對(duì)象如何創(chuàng)建元媚,如何協(xié)作等轧叽,當(dāng)我們開(kāi)發(fā)一個(gè)項(xiàng)目時(shí),框架幫助我們完成了一部分功能刊棕,我們自己再完成一部分,那這個(gè)項(xiàng)目就完成了待逞。
2)什么是 Spring 甥角?
Spring 是一個(gè)輕量級(jí)的 DI / IoC 和 AOP 容器的開(kāi)源框架,來(lái)源于 Rod Johnson 在其著作《Expert one on one J2EE design and development》中闡述的部分理念和原型衍生而來(lái)识樱。
Spring 提倡以 “最少侵入” 的方式來(lái)管理應(yīng)用中的代碼嗤无,這意味著我們可以隨時(shí)安裝或者卸載 Spring
- 適用范圍:任何 Java 應(yīng)用
- Spring 的根本使命:簡(jiǎn)化 Java 開(kāi)發(fā)
3)什么是非侵入式設(shè)計(jì)?
從框架的角度可以理解為:無(wú)需繼承框架提供的任何類(lèi)
這樣我們?cè)诟鼡Q框架時(shí)怜庸,之前寫(xiě)過(guò)的代碼幾乎可以繼續(xù)使用当犯。
4)Spring 有什么優(yōu)勢(shì)?
- 低侵入 / 低耦合 (降低組件之間的耦合度割疾,實(shí)現(xiàn)軟件各層之間的解耦)
- 聲明式事務(wù)管理(基于切面和慣例)
- 方便集成其他框架(如MyBatis嚎卫、Hibernate)
- 降低 Java 開(kāi)發(fā)難度
- Spring 框架中包括了 J2EE 三層的每一層的解決方案(一站式)
Spring 的框架結(jié)構(gòu)
- Data Access/Integration層包含有JDBC、ORM宏榕、OXM拓诸、JMS和Transaction模塊。
- Web層包含了Web麻昼、Web-Servlet奠支、WebSocket、Web-Porlet模塊抚芦。
- AOP模塊提供了一個(gè)符合AOP聯(lián)盟標(biāo)準(zhǔn)的面向切面編程的實(shí)現(xiàn)倍谜。
- Core Container(核心容器):包含有Beans迈螟、Core惕蹄、Context和SpEL模塊摔寨。
- Test模塊支持使用JUnit和TestNG對(duì)Spring組件進(jìn)行測(cè)試氧秘。
5)Spring IoC 和 DI 分別是什么露泊?
Spring IoC
IoC:Inverse of Control(控制反轉(zhuǎn))斗塘,讀作 “反轉(zhuǎn)控制”溉痢,更好理解荆永,不是什么技術(shù)召耘,而是一種設(shè)計(jì)思想鹤盒,就是將原本在程序中手動(dòng)創(chuàng)建對(duì)象的控制權(quán)蚕脏,交由Spring框架來(lái)管理。
- 正控:若要使用某個(gè)對(duì)象侦锯,需要自己去負(fù)責(zé)對(duì)象的創(chuàng)建
- 反控:若要使用某個(gè)對(duì)象驼鞭,只需要從 Spring 容器中獲取需要使用的對(duì)象,不關(guān)心對(duì)象的創(chuàng)建過(guò)程尺碰,也就是把創(chuàng)建對(duì)象的控制權(quán)反轉(zhuǎn)給了Spring框架
- 好萊塢法則:Don’t call me ,I’ll call you
為了便于理解我們這里舉一個(gè)鮮明的例子:
在現(xiàn)實(shí)生活中挣棕,人們要用到一樣?xùn)|西的時(shí)候,第一反應(yīng)就是去找到這件東西亲桥,比如想喝新鮮橙汁洛心,在沒(méi)有飲品店的日子里,最直觀的做法就是:買(mǎi)果汁機(jī)题篷、買(mǎi)橙子词身,然后準(zhǔn)備開(kāi)水。值得注意的是:這些都是你自己“主動(dòng)”創(chuàng)造的過(guò)程番枚,也就是說(shuō)一杯橙汁需要你自己創(chuàng)造法严。
然而到了今時(shí)今日,由于飲品店的盛行葫笼,當(dāng)我們想喝橙汁時(shí)深啤,第一想法就轉(zhuǎn)換成了找到飲品店的聯(lián)系方式,通過(guò)電話等渠道描述你的需要路星、地址溯街、聯(lián)系方式等,下訂單等待奥额,過(guò)一會(huì)兒就會(huì)有人送來(lái)橙汁了苫幢。
請(qǐng)注意你并沒(méi)有“主動(dòng)”去創(chuàng)造橙汁,橙汁是由飲品店創(chuàng)造的垫挨,而不是你韩肝,然而也完全達(dá)到了你的要求,甚至比你創(chuàng)造的要好上那么一些九榔。
- 總結(jié): 這就是一種控制反轉(zhuǎn)的理念哀峻,上述的例子已經(jīng)很好的說(shuō)明了問(wèn)題涡相,我們?cè)賮?lái)描述一下控制反轉(zhuǎn)的概念:控制反轉(zhuǎn)是一種通過(guò)描述(在 Java 中可以是 XML 或者注解)并通過(guò)第三方(Spring)去產(chǎn)生或獲取特定對(duì)象的方式。
- 好處: ① 降低對(duì)象之間的耦合剩蟀;② 我們不需要理解一個(gè)類(lèi)的具體實(shí)現(xiàn)催蝗,只需要知道它有什么用就好了(直接向 IoC 容器拿)
DI:Dependency Injection(依賴(lài)注入)
指 Spring 創(chuàng)建對(duì)象的過(guò)程中,將對(duì)象依賴(lài)屬性(簡(jiǎn)單值育特,集合丙号,對(duì)象)通過(guò)配置設(shè)值給該對(duì)象
兩者的區(qū)別
IoC 和 DI 其實(shí)是同一個(gè)概念的不同角度描述,DI 相對(duì) IoC 而言缰冤,明確描述了 “被注入對(duì)象依賴(lài) IoC 容器配置依賴(lài)對(duì)象”犬缨。
你也可以簡(jiǎn)單的理解為:IoC 是目的,是一種思想棉浸,而 DI 是手段怀薛,是一種設(shè)計(jì)模式。
6)BeanFactory 和 ApplicationContext 的區(qū)別
1.BeanFactory:
是Spring中最底層的接口迷郑,只提供了最簡(jiǎn)單的IoC功能,負(fù)責(zé)配置枝恋,創(chuàng)建和管理bean。在應(yīng)用中嗡害,一般不使用 BeanFactory焚碌,而推薦使ApplicationContext(應(yīng)用上下文),原因如下霸妹。
2.ApplicationContext:
⑴. 繼承了 BeanFactory呐能,擁有了基本的 IoC 功能;
⑵. 除此之外抑堡,ApplicationContext 還提供了以下功能:
① 支持國(guó)際化;② 支持消息機(jī)制朗徊;③ 支持統(tǒng)一的資源加載首妖;④ 支持AOP功能;
- 注意: ApplicationContext 和 BeanFactory 相比爷恳,最主要的區(qū)別在于 BeanFactory 是延遲加載有缆,舉個(gè)例子:如果 Bean 沒(méi)有完全注入,BeanFactory 加載后温亲,會(huì)在你第一次調(diào)用 getBean 方法才會(huì)拋出異常棚壁;而 ApplicationContext 會(huì)在初始化的時(shí)候就加載并且檢查,這樣的好處是可以及時(shí)檢查依賴(lài)是否完全注入栈虚;所以通常我們會(huì)選擇 ApplicationContext袖外。
7)IoC 是如何實(shí)現(xiàn)的
最后我們簡(jiǎn)單說(shuō)說(shuō)IoC是如何實(shí)現(xiàn)的。想象一下如果我們自己來(lái)實(shí)現(xiàn)這個(gè)依賴(lài)注入的功能魂务,我們?cè)趺磥?lái)做曼验? 無(wú)外乎:
- 讀取標(biāo)注或者配置文件泌射,看看JuiceMaker依賴(lài)的是哪個(gè)Source,拿到類(lèi)名
- 使用反射的API鬓照,基于類(lèi)名實(shí)例化對(duì)應(yīng)的對(duì)象實(shí)例
- 將對(duì)象實(shí)例熔酷,通過(guò)構(gòu)造函數(shù)或者 setter,傳遞給 JuiceMaker
我們發(fā)現(xiàn)其實(shí)自己來(lái)實(shí)現(xiàn)也不是很難豺裆,Spring實(shí)際也就是這么做的拒秘。這么看的話其實(shí)IoC就是一個(gè)工廠模式的升級(jí)版!當(dāng)然要做一個(gè)成熟的IoC框架臭猜,還是非常多細(xì)致的工作要做躺酒,Spring不僅提供了一個(gè)已經(jīng)成為業(yè)界標(biāo)準(zhǔn)的Java IoC框架,還提供了更多強(qiáng)大的功能获讳,所以大家就別去造輪子啦阴颖!希望了解IoC更多實(shí)現(xiàn)細(xì)節(jié)不妨通過(guò)學(xué)習(xí)Spring的源碼來(lái)加深理解!
引用地址:這里
8)Spring 配置 Bean 有幾種方式丐膝?
在 Spring 中提供了 3 種方法進(jìn)行配置:
- 在 XML 文件中顯式配置
- 在 Java 的接口和類(lèi)中實(shí)現(xiàn)配置
- 隱式 Bean 的發(fā)現(xiàn)機(jī)制和自動(dòng)裝配原則
方式選擇的原則
在現(xiàn)實(shí)的工作中量愧,這 3 種方式都會(huì)被用到,并且在學(xué)習(xí)和工作之中常乘Т#混合使用偎肃,所以這里給出一些關(guān)于這 3 種優(yōu)先級(jí)的建議:
1.最優(yōu)先:通過(guò)隱式 Bean 的發(fā)現(xiàn)機(jī)制和自動(dòng)裝配的原則。
基于約定由于配置的原則浑此,這種方式應(yīng)該是最優(yōu)先的
- 好處:減少程序開(kāi)發(fā)者的決定權(quán)累颂,簡(jiǎn)單又不失靈活。
2.其次:Java 接口和類(lèi)中配置實(shí)現(xiàn)配置
在沒(méi)有辦法使用自動(dòng)裝配原則的情況下應(yīng)該優(yōu)先考慮此類(lèi)方法
- 好處:避免 XML 配置的泛濫凛俱,也更為容易紊馏。
- 典型場(chǎng)景:一個(gè)父類(lèi)有多個(gè)子類(lèi),比如學(xué)生類(lèi)有兩個(gè)子類(lèi)蒲犬,一個(gè)男學(xué)生類(lèi)和女學(xué)生類(lèi)朱监,通過(guò) IoC 容器初始化一個(gè)學(xué)生類(lèi),容器將無(wú)法知道使用哪個(gè)子類(lèi)去初始化原叮,這個(gè)時(shí)候可以使用 Java 的注解配置去指定赫编。
3.最后:XML 方式配置
在上述方法都無(wú)法使用的情況下,那么也只能選擇 XML 配置的方式奋隶。
- 好處:簡(jiǎn)單易懂(當(dāng)然擂送,特別是對(duì)于初學(xué)者)
- 典型場(chǎng)景:當(dāng)使用第三方類(lèi)的時(shí)候,有些類(lèi)并不是我們開(kāi)發(fā)的唯欣,我們無(wú)法修改里面的代碼嘹吨,這個(gè)時(shí)候就通過(guò) XML 的方式配置使用了。
9)介紹一下 Spring AOP
AOP 即 Aspect Oriented Program 面向切面編程
首先黍聂,在面向切面編程的思想里面躺苦,把功能分為核心業(yè)務(wù)功能身腻,和周邊功能。
- 所謂的核心業(yè)務(wù)匹厘,比如登陸嘀趟,增加數(shù)據(jù),刪除數(shù)據(jù)都叫核心業(yè)務(wù)
- 所謂的周邊功能愈诚,比如性能統(tǒng)計(jì)她按,日志,事務(wù)管理等等
周邊功能在 Spring 的面向切面編程AOP思想里炕柔,即被定義為切面
在面向切面編程AOP的思想里面酌泰,核心業(yè)務(wù)功能和切面功能分別獨(dú)立進(jìn)行開(kāi)發(fā),然后把切面功能和核心業(yè)務(wù)功能 "編織" 在一起匕累,這就叫 AOP
還是來(lái)舉一個(gè)鮮明的例子:
在上面的例子中陵刹,包租婆的核心業(yè)務(wù)就是簽合同,收房租欢嘿,那么這就夠了衰琐,灰色框起來(lái)的部分都是重復(fù)且邊緣的事,交給中介商就好了炼蹦,這就是 AOP 的一個(gè)思想:讓關(guān)注點(diǎn)代碼與業(yè)務(wù)代碼分離羡宙!
10)Spring 中 Bean 的作用域
在默認(rèn)的情況下,Spring IoC 容器只會(huì)對(duì)一個(gè) Bean 創(chuàng)建一個(gè)實(shí)例掐隐,但有時(shí)候狗热,我們希望能夠通過(guò) Spring IoC 容器獲取多個(gè)實(shí)例,我們可以通過(guò) @Scope
注解或者 <bean>
元素中的 scope
屬性來(lái)設(shè)置虑省,例如:
// XML 中設(shè)置作用域
<bean id="" class="" scope="prototype" />
// 使用注解設(shè)置作用域
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
Spring 提供了 5 種作用域匿刮,它會(huì)根據(jù)情況來(lái)決定是否生成新的對(duì)象:
作用域類(lèi)別 | 描述 |
---|---|
singleton(單例) | 在Spring IoC容器中僅存在一個(gè)Bean實(shí)例 (默認(rèn)的scope) |
prototype(多例) | 每次從容器中調(diào)用Bean時(shí),都返回一個(gè)新的實(shí)例探颈,即每次調(diào)用getBean()時(shí) 僻焚,相當(dāng)于執(zhí)行new XxxBean():不會(huì)在容器啟動(dòng)時(shí)創(chuàng)建對(duì)象 |
request(請(qǐng)求) | 用于web開(kāi)發(fā),將Bean放入request范圍 膝擂,request.setAttribute("xxx") , 在同一個(gè)request 獲得同一個(gè)Bean |
session(會(huì)話) | 用于web開(kāi)發(fā)隙弛,將Bean 放入Session范圍架馋,在同一個(gè)Session 獲得同一個(gè)Bean |
globalSession(全局會(huì)話) | 一般用于 Porlet 應(yīng)用環(huán)境 , 分布式系統(tǒng)存在全局 session 概念(單點(diǎn)登錄),如果不是 porlet 環(huán)境全闷,globalSession 等同于 Session |
在開(kāi)發(fā)中主要使用 scope="singleton"
叉寂、scope="prototype"
,對(duì)于MVC中的Action使用prototype類(lèi)型总珠,其他使用singleton屏鳍,Spring容器會(huì)管理 Action 對(duì)象的創(chuàng)建,此時(shí)把 Action 的作用域設(shè)置為 prototype.
擴(kuò)展閱讀:@Profile 注解 勘纯、 條件化裝配 Bean
11)Spring 面試問(wèn)答 Top 25
更多戳這里:Spring面試問(wèn)答Top 25
12)Spring MVC 的請(qǐng)求流程
每當(dāng)用戶在 Web 瀏覽器中點(diǎn)擊鏈接或者提交表單的時(shí)候,請(qǐng)求就開(kāi)始工作了钓瞭,像是郵遞員一樣驳遵,從離開(kāi)瀏覽器開(kāi)始到獲取響應(yīng)返回,它會(huì)經(jīng)歷很多站點(diǎn)山涡,在每一個(gè)站點(diǎn)都會(huì)留下一些信息同時(shí)也會(huì)帶上其他信息堤结,下圖為 Spring MVC 的請(qǐng)求流程:
第一站:DispatcherServlet
從請(qǐng)求離開(kāi)瀏覽器以后,第一站到達(dá)的就是 DispatcherServlet鸭丛,看名字這是一個(gè) Servlet竞穷,通過(guò) J2EE 的學(xué)習(xí),我們知道 Servlet 可以攔截并處理 HTTP 請(qǐng)求鳞溉,DispatcherServlet 會(huì)攔截所有的請(qǐng)求瘾带,并且將這些請(qǐng)求發(fā)送給 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>
<!-- 攔截所有的請(qǐng)求 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
- DispatcherServlet 的任務(wù)就是攔截請(qǐng)求發(fā)送給 Spring MVC 控制器熟菲。
第二站:處理器映射(HandlerMapping)
- 問(wèn)題:典型的應(yīng)用程序中可能會(huì)有多個(gè)控制器看政,這些請(qǐng)求到底應(yīng)該發(fā)給哪一個(gè)控制器呢?
所以 DispatcherServlet 會(huì)查詢(xún)一個(gè)或多個(gè)處理器映射來(lái)確定請(qǐng)求的下一站在哪里科盛,處理器映射會(huì)根據(jù)請(qǐng)求所攜帶的 URL 信息來(lái)進(jìn)行決策帽衙,例如上面的例子中,我們通過(guò)配置 simpleUrlHandlerMapping 來(lái)將 /hello 地址交給 helloController 處理:
<bean id="simpleUrlHandlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<!-- /hello 路徑的請(qǐng)求交給 id 為 helloController 的控制器處理-->
<prop key="/hello">helloController</prop>
</props>
</property>
</bean>
<bean id="helloController" class="controller.HelloController"></bean>
第三站:控制器
一旦選擇了合適的控制器贞绵, DispatcherServlet 會(huì)將請(qǐng)求發(fā)送給選中的控制器厉萝,到了控制器,請(qǐng)求會(huì)卸下其負(fù)載(用戶提交的請(qǐng)求)等待控制器處理完這些信息:
public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
// 處理邏輯
....
}
第四站:返回 DispatcherServlet
當(dāng)控制器在完成邏輯處理后榨崩,通常會(huì)產(chǎn)生一些信息谴垫,這些信息就是需要返回給用戶并在瀏覽器上顯示的信息,它們被稱(chēng)為模型(Model)母蛛。僅僅返回原始的信息時(shí)不夠的——這些信息需要以用戶友好的方式進(jìn)行格式化翩剪,一般會(huì)是 HTML,所以彩郊,信息需要發(fā)送給一個(gè)視圖(view)前弯,通常會(huì)是 JSP。
控制器所做的最后一件事就是將模型數(shù)據(jù)打包秫逝,并且表示出用于渲染輸出的視圖名(邏輯視圖名)恕出。它接下來(lái)會(huì)將請(qǐng)求連同模型和視圖名發(fā)送回 DispatcherServlet。
public ModelAndView handleRequest(javax.servlet.http.HttpServletRequest httpServletRequest, javax.servlet.http.HttpServletResponse httpServletResponse) throws Exception {
// 處理邏輯
....
// 返回給 DispatcherServlet
return mav;
}
第五站:視圖解析器
這樣以來(lái)违帆,控制器就不會(huì)和特定的視圖相耦合浙巫,傳遞給 DispatcherServlet 的視圖名并不直接表示某個(gè)特定的 JSP。(實(shí)際上,它甚至不能確定視圖就是 JSP)相反的畴,它傳遞的僅僅是一個(gè)邏輯名稱(chēng)渊抄,這個(gè)名稱(chēng)將會(huì)用來(lái)查找產(chǎn)生結(jié)果的真正視圖。
DispatcherServlet 將會(huì)使用視圖解析器(view resolver)來(lái)將邏輯視圖名匹配為一個(gè)特定的視圖實(shí)現(xiàn)丧裁,它可能是也可能不是 JSP
上面的例子是直接綁定到了 index.jsp 視圖
第六站:視圖
既然 DispatcherServlet 已經(jīng)知道由哪個(gè)視圖渲染結(jié)果了护桦,那請(qǐng)求的任務(wù)基本上也就完成了。
它的最后一站是視圖的實(shí)現(xiàn)渣慕,在這里它交付模型數(shù)據(jù)嘶炭,請(qǐng)求的任務(wù)也就完成了。視圖使用模型數(shù)據(jù)渲染出結(jié)果逊桦,這個(gè)輸出結(jié)果會(huì)通過(guò)響應(yīng)對(duì)象傳遞給客戶端眨猎。
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" isELIgnored="false"%>
<h1>${message}</h1>
更多 Spring-MVC 內(nèi)容:Spring MVC【入門(mén)】就這一篇
13)什么是 ORM?
對(duì)象關(guān)系映射(Object-Relational Mapping强经,簡(jiǎn)稱(chēng)ORM)是一種為了解決程序的面向?qū)ο竽P团c數(shù)據(jù)庫(kù)的關(guān)系模型互不匹配問(wèn)題的技術(shù)睡陪;
簡(jiǎn)單的說(shuō),ORM是通過(guò)使用描述對(duì)象和數(shù)據(jù)庫(kù)之間映射的元數(shù)據(jù)(在Java中可以用XML或者是注解)匿情,將程序中的對(duì)象自動(dòng)持久化到關(guān)系數(shù)據(jù)庫(kù)中或者將關(guān)系數(shù)據(jù)庫(kù)表中的行轉(zhuǎn)換成Java對(duì)象兰迫,其本質(zhì)上就是將數(shù)據(jù)從一種形式轉(zhuǎn)換到另外一種形式。
14)為什么要使用 MyBatis 炬称?
在我們傳統(tǒng)的 JDBC 中汁果,我們除了需要自己提供 SQL 外,還必須操作 Connection玲躯、Statment据德、ResultSet,不僅如此跷车,為了訪問(wèn)不同的表棘利,不同字段的數(shù)據(jù),我們需要些很多雷同模板化的代碼朽缴,閑的繁瑣又枯燥善玫。
而我們?cè)谑褂昧?MyBatis 之后,只需要提供 SQL 語(yǔ)句就好了密强,其余的諸如:建立連接茅郎、操作 Statment、ResultSet或渤,處理 JDBC 相關(guān)異常等等都可以交給 MyBatis 去處理只洒,我們的關(guān)注點(diǎn)于是可以就此集中在 SQL 語(yǔ)句上,關(guān)注在增刪改查這些操作層面上劳坑。
并且 MyBatis 支持使用簡(jiǎn)單的 XML 或注解來(lái)配置和映射原生信息,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對(duì)象)映射成數(shù)據(jù)庫(kù)中的記錄成畦。
15)MyBatis 中占位符 #
和 $
的區(qū)別
區(qū)別如下:
-
#
符號(hào)將傳入的數(shù)據(jù)都當(dāng)做一個(gè)字符串距芬,會(huì)對(duì)自動(dòng)傳入的數(shù)據(jù)加一個(gè)雙引號(hào) -
$
符號(hào)將傳入的數(shù)據(jù)直接顯示生成SQL中涝开。 -
#
符號(hào)存在預(yù)編譯的過(guò)程,框仔,對(duì)問(wèn)號(hào)賦值舀武,防止SQL注入。 -
$
符號(hào)是直譯的方式离斩,一般用在orderby {列名} 語(yǔ)句中银舱。 - 能用
#
號(hào)就不要用$
符號(hào)
16)MyBatis 緩存結(jié)構(gòu)
在 Web 系統(tǒng)中,最重要的操作就是查詢(xún)數(shù)據(jù)庫(kù)中的數(shù)據(jù)跛梗。但是有些時(shí)候查詢(xún)數(shù)據(jù)的頻率非常高寻馏,這是很耗費(fèi)數(shù)據(jù)庫(kù)資源的,往往會(huì)導(dǎo)致數(shù)據(jù)庫(kù)查詢(xún)效率極低核偿,影響客戶的操作體驗(yàn)诚欠。于是我們可以將一些變動(dòng)不大且訪問(wèn)頻率高的數(shù)據(jù),放置在一個(gè)緩存容器中漾岳,用戶下一次查詢(xún)時(shí)就從緩存容器中獲取結(jié)果轰绵。
- MyBatis 擁有自己的緩存結(jié)構(gòu),可以用來(lái)緩解數(shù)據(jù)庫(kù)壓力尼荆,加快查詢(xún)速度左腔。
- MyBatis 一級(jí)緩存是一個(gè) SqlSession 級(jí)別,同一個(gè) SqlSession 只能訪問(wèn)自己的一級(jí)緩存的數(shù)據(jù)
- 二級(jí)緩存是跨sqlSession捅儒,是 mapper 級(jí)別的緩存液样,對(duì)于 mapper 級(jí)別的緩存不同的sqlsession是可以共享的。
更多深入MyBatis的內(nèi)容戳這里:MyBatis(2)——MyBatis 深入學(xué)習(xí)
17)MyBatis 與 Spring 整合
18)IDEA 整合 SSM 框架學(xué)習(xí)
19)MVC 三種模式
在早期 Java Web 的開(kāi)發(fā)中野芒,統(tǒng)一把顯示層蓄愁、控制層、數(shù)據(jù)層的操作全部交給 JSP 或者 JavaBean 來(lái)進(jìn)行處理狞悲,我們稱(chēng)之為 Model1:
- 出現(xiàn)的弊端:
- JSP 和 Java Bean 之間嚴(yán)重耦合撮抓,Java 代碼和 HTML 代碼也耦合在了一起
- 要求開(kāi)發(fā)者不僅要掌握 Java ,還要有高超的前端水平
- 前端和后端相互依賴(lài)摇锋,前端需要等待后端完成丹拯,后端也依賴(lài)前端完成,才能進(jìn)行有效的測(cè)試
- 代碼難以復(fù)用
正因?yàn)樯厦娴姆N種弊端荸恕,所以很快這種方式就被 Servlet + JSP + Java Bean 所替代了乖酬,早期的 MVC 模型(Model2)就像下圖這樣:
首先用戶的請(qǐng)求會(huì)到達(dá) Servlet,然后根據(jù)請(qǐng)求調(diào)用相應(yīng)的 Java Bean融求,并把所有的顯示結(jié)果交給 JSP 去完成咬像,這樣的模式我們就稱(chēng)為 MVC 模式。
-
M 代表 模型(Model)
模型是什么呢? 模型就是數(shù)據(jù)县昂,就是 dao,bean -
V 代表 視圖(View)
視圖是什么呢肮柜? 就是網(wǎng)頁(yè), JSP,用來(lái)展示模型中的數(shù)據(jù) -
C 代表 控制器(controller)
控制器是什么倒彰? 控制器的作用就是把不同的數(shù)據(jù)(Model)审洞,顯示在不同的視圖(View)上,Servlet 扮演的就是這樣的角色待讳。
擴(kuò)展閱讀:Web開(kāi)發(fā)模式
Spring MVC 的架構(gòu)
為解決持久層中一直未處理好的數(shù)據(jù)庫(kù)事務(wù)的編程芒澜,又為了迎合 NoSQL 的強(qiáng)勢(shì)崛起,Spring MVC 給出了方案:
傳統(tǒng)的模型層被拆分為了業(yè)務(wù)層(Service)和數(shù)據(jù)訪問(wèn)層(DAO,Data Access Object)创淡。在 Service 下可以通過(guò) Spring 的聲明式事務(wù)操作數(shù)據(jù)訪問(wèn)層痴晦,而在業(yè)務(wù)層上還允許我們?cè)L問(wèn) NoSQL ,這樣就能夠滿足異軍突起的 NoSQL 的使用了辩昆,它可以大大提高互聯(lián)網(wǎng)系統(tǒng)的性能阅酪。
-
特點(diǎn):
結(jié)構(gòu)松散,幾乎可以在 Spring MVC 中使用各類(lèi)視圖
松耦合汁针,各個(gè)模塊分離
與 Spring 無(wú)縫集成
20)分頁(yè)术辐?
21)什么是 Spring Boot ?
- 它使用 “習(xí)慣優(yōu)于配置” (項(xiàng)目中存在大量的配置施无,此外還內(nèi)置一個(gè)習(xí)慣性的配置辉词,讓你無(wú)須)的理念讓你的項(xiàng)目快速運(yùn)行起來(lái)。
- 它并不是什么新的框架猾骡,而是默認(rèn)配置了很多框架的使用方式瑞躺,就像 Maven 整合了所有的 jar 包一樣,Spring Boot 整合了所有框架(引自:springboot(一):入門(mén)篇——純潔的微笑)
22)使用 Spring Boot 有什么好處兴想?
回顧我們之前的 SSM 項(xiàng)目幢哨,搭建過(guò)程還是比較繁瑣的,需要:
- 1)配置 web.xml嫂便,加載 spring 和 spring mvc
- 2)配置數(shù)據(jù)庫(kù)連接捞镰、配置日志文件
- 3)配置家在配置文件的讀取,開(kāi)啟注解
- 4)配置mapper文件
- .....
而使用 Spring Boot 來(lái)開(kāi)發(fā)項(xiàng)目則只需要非常少的幾個(gè)配置就可以搭建起來(lái)一個(gè) Web 項(xiàng)目毙替,并且利用 IDEA 可以自動(dòng)生成生成岸售,這簡(jiǎn)直是太爽了...
- 劃重點(diǎn):簡(jiǎn)單、快速厂画、方便地搭建項(xiàng)目凸丸;對(duì)主流開(kāi)發(fā)框架的無(wú)配置集成;極大提高了開(kāi)發(fā)袱院、部署效率屎慢。
Spring Boot 由于筆者還沒(méi)有深入學(xué)習(xí)..所以細(xì)節(jié)部分請(qǐng)讀者自行收集...
歡迎轉(zhuǎn)載瞭稼,轉(zhuǎn)載請(qǐng)注明出處!
簡(jiǎn)書(shū)ID:@我沒(méi)有三顆心臟
github:wmyskxz
歡迎關(guān)注公眾微信號(hào):wmyskxz_javaweb
分享自己的Java Web學(xué)習(xí)之路以及各種Java學(xué)習(xí)資料