javascript
Servlet/Tomcat/ Spring 之间的关系
0.基礎(chǔ)知識
在idea中打開servlet的源碼:
?
?
可以看見servlet就是一個接口;接口就是規(guī)定了一些規(guī)范,使得一些具有某些共性的類都能實(shí)現(xiàn)這個接口,從而都遵循某些規(guī)范。
有的人往往以為就是servlet直接處理客戶端的http請求,其實(shí)并不是這樣,servlet并不會去監(jiān)聽8080端口;直接與客戶端打交道是“容器”,比如常用的tomcat。
客戶端的請求直接打到tomcat,它監(jiān)聽端口,請求過來后,根據(jù)url等信息,確定要將請求交給哪個servlet去處理,然后調(diào)用那個servlet的service方法,service方法返回一個response對象,tomcat再把這個response返回給客戶端。
?
?
1. Servlet的生命周期
?
從創(chuàng)建到毀滅:
?
?
由上面可以看見,servlet的init方法和destroy方法,一般容器調(diào)用這兩個方法之間的過程,就叫做servlet的生命周期。
調(diào)用的整個過程就如上圖所示。
當(dāng)請求來容器第一次調(diào)用某個servlet時,需要先初始化init(),
但當(dāng)某個請求再次打到給servlet時,容器會起多個線程同時訪問一個servlet的service()方法。
?
?
由此可以看出,多個客戶訪問同一service()方法,會涉及線程安全的問題。
?
如果service()方法沒有訪問Servlet的成員變量也沒有訪問全局的資源比如靜態(tài)變量、文件、數(shù)據(jù)庫連接等,而是只使用了當(dāng)前線程自己的資源,比如非指向全局資源的臨時變量、request和response對象等。該方法本身就是線程安全的,不必進(jìn)行任何的同步控制。
如果service()方法訪問了Servlet的成員變量,但是對該變量的操作是只讀操作,該方法本身就是線程安全的,不必進(jìn)行任何的同步控制。
如果service()方法訪問了Servlet的成員變量,并且對該變量的操作既有讀又有寫,通常需要加上同步控制語句。
如果service()方法訪問了全局的靜態(tài)變量,如果同一時刻系統(tǒng)中也可能有其它線程訪問該靜態(tài)變量,如果既有讀也有寫的操作,通常需要加上同步控制語句。
如果service()方法訪問了全局的資源,比如文件、數(shù)據(jù)庫連接等,通常需要加上同步控制語句。
?
?
面試問題:Servlet如何同時處理多個請求訪問??
單實(shí)例多線程:?主要是請求來時,會由線程調(diào)度者從線程池李取出來一個線程,來作為響應(yīng)線程。這個線程可能是已經(jīng)實(shí)例化的,也可能是新創(chuàng)建的。
Servlet容器默認(rèn)是采用單實(shí)例多線程的方式處理多個請求的:?
1.當(dāng)web服務(wù)器啟動的時候(或客戶端發(fā)送請求到服務(wù)器時),Servlet就被加載并實(shí)例化(只存在一個Servlet實(shí)例);?
2.容器初始化化Servlet主要就是讀取配置文件(例如tomcat,可以通過servlet.xml的設(shè)置線程池中線程數(shù)目,初始化線程池通過web.xml,初始化每個參數(shù)值等等。?
3.當(dāng)請求到達(dá)時,Servlet容器通過調(diào)度線程(Dispatchaer Thread) 調(diào)度它管理下線程池中等待執(zhí)行的線程(Worker Thread)給請求者;?
4.線程執(zhí)行Servlet的service方法;?
5.請求結(jié)束,放回線程池,等待被調(diào)用;?
(注意:避免使用實(shí)例變量(成員變量),因為如果存在成員變量,可能發(fā)生多線程同時訪問該資源時,都來操作它,照成數(shù)據(jù)的不一致,因此產(chǎn)生線程安全問題)
?
從上面可以看出:?
第一:Servlet單實(shí)例,減少了產(chǎn)生servlet的開銷;?
第二:通過線程池來響應(yīng)多個請求,提高了請求的響應(yīng)時間;?
第三:Servlet容器并不關(guān)心到達(dá)的Servlet請求訪問的是否是同一個Servlet還是另一個Servlet,直接分配給它一個新的線程;如果是同一個Servlet的多個請求,那么Servlet的service方法將在多線程中并發(fā)的執(zhí)行;?
第四:每一個請求由ServletRequest對象來接受請求,由ServletResponse對象來響應(yīng)該請求;
?
?
?
?
?2. Spring?
?
?任何Spring Web的entry point,都是servlet。
?
大名頂頂?shù)膕pring框架已經(jīng)風(fēng)靡多時,一個事物的出現(xiàn)和流行都是會有原因的,那么為什么spring 框架會出現(xiàn)呢?原因就是為了簡化java開發(fā)。
spring的核心就是通過依賴注入、面向切面編程aop、和模版技術(shù),解耦業(yè)務(wù)與系統(tǒng)服務(wù),消除重復(fù)代碼。借助aop,可以將遍布應(yīng)用的關(guān)注點(diǎn)(如事物和安全)從它們的應(yīng)用對象中解耦出來。
?
?
?Spring 中的Bean
?1)?POJO和JavaBean的區(qū)別 :?
"Plain Ordinary Java Object",簡單普通的java對象。主要用來指代那些沒有遵循特定的java對象模型,約定或者框架的對象。
POJO的內(nèi)在含義是指那些:
有一些private的參數(shù)作為對象的屬性,然后針對每一個參數(shù)定義get和set方法訪問的接口。
沒有從任何類繼承、也沒有實(shí)現(xiàn)任何接口,更沒有被其它框架侵入的java對象。
JavaBean 是一種JAVA語言寫成的可重用組件。JavaBean符合一定規(guī)范編寫的Java類,不是一種技術(shù),而是一種規(guī)范。大家針對這種規(guī)范,總結(jié)了很多開發(fā)技巧、工具函數(shù)。符合這種規(guī)范的類,可以被其它的程序員或者框架使用。它的方法命名,構(gòu)造及行為必須符合特定的約定:
所有屬性為private。
這個類必須有一個公共的缺省構(gòu)造函數(shù)。即是提供無參數(shù)的構(gòu)造器。
這個類的屬性使用getter和setter來訪問,其他方法遵從標(biāo)準(zhǔn)命名規(guī)范。
這個類應(yīng)是可序列化的。實(shí)現(xiàn)serializable接口。
因為這些要求主要是靠約定而不是靠實(shí)現(xiàn)接口,所以許多開發(fā)者把JavaBean看作遵從特定命名約定的POJO。
?
spring中,應(yīng)用對西那個生存于spring容器中,spring 容器創(chuàng)建對象,裝配它們,管理它們的整個生命周期。spring容器通過依賴注入,管理構(gòu)成應(yīng)用的組件,它會創(chuàng)建相互協(xié)作的組件之間的關(guān)聯(lián)。
2) Bean的生命周期
?
?
?Spring MVC
?
?
?
?
?Spring MVC的運(yùn)行流程:
?
?
?
來源:https://www.cnblogs.com/shawshawwan/p/9002126.html
總結(jié)
以上是生活随笔為你收集整理的Servlet/Tomcat/ Spring 之间的关系的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浙四医院官网APP(浙四医院官网)
- 下一篇: 什么是机械化战争?其主要特征是什么?