0.基礎知識java
在idea中打開servlet的源碼:程序員
能夠看見servlet就是一個接口;接口就是規定了一些規範,使得一些具備某些共性的類都能實現這個接口,從而都遵循某些規範。web
有的人每每覺得就是servlet直接處理客戶端的http請求,其實並非這樣,servlet並不會去監聽8080端口;直接與客戶端打交道是「容器」,好比經常使用的tomcat。面試
客戶端的請求直接打到tomcat,它監聽端口,請求過來後,根據url等信息,肯定要將請求交給哪一個servlet去處理,而後調用那個servlet的service方法,service方法返回一個response對象,tomcat再把這個response返回給客戶端。spring
1. Servlet的生命週期數據庫
從建立到毀滅:編程
init()
方法初始化service()
方法來處理客戶端的請求destroy()
方法釋放資源,標記自身爲可回收
由上面能夠看見,servlet的init方法和destroy方法,通常容器調用這兩個方法之間的過程,就叫作servlet的生命週期。tomcat
調用的整個過程就如上圖所示。安全
當請求來容器第一次調用某個servlet時,須要先初始化init(),服務器
但當某個請求再次打到給servlet時,容器會起多個線程同時訪問一個servlet的service()方法。
由此能夠看出,多個客戶訪問同一service()方法,會涉及線程安全的問題。
若是service()方法沒有訪問Servlet的成員變量也沒有訪問全局的資源好比靜態變量、文件、數據庫鏈接等,而是隻使用了當前線程本身的資源,好比非指向全局資源的臨時變量、request和response對象等。該方法自己就是線程安全的,沒必要進行任何的同步控制。
若是service()方法訪問了Servlet的成員變量,可是對該變量的操做是隻讀操做,該方法自己就是線程安全的,沒必要進行任何的同步控制。
若是service()方法訪問了Servlet的成員變量,而且對該變量的操做既有讀又有寫,一般須要加上同步控制語句。
若是service()方法訪問了全局的靜態變量,若是同一時刻系統中也可能有其它線程訪問該靜態變量,若是既有讀也有寫的操做,一般須要加上同步控制語句。
若是service()方法訪問了全局的資源,好比文件、數據庫鏈接等,一般須要加上同步控制語句。
面試問題:Servlet如何同時處理多個請求訪問?
單實例多線程: 主要是請求來時,會由線程調度者從線程池李取出來一個線程,來做爲響應線程。這個線程多是已經實例化的,也多是新建立的。
Servlet容器默認是採用單實例多線程的方式處理多個請求的:
1.當web服務器啓動的時候(或客戶端發送請求到服務器時),Servlet就被加載並實例化(只存在一個Servlet實例);
2.容器初始化化Servlet主要就是讀取配置文件(例如tomcat,能夠經過servlet.xml的設置線程池中線程數目,初始化線程池經過web.xml,初始化每一個參數值等等。
3.當請求到達時,Servlet容器經過調度線程(Dispatchaer Thread) 調度它管理下線程池中等待執行的線程(Worker Thread)給請求者;
4.線程執行Servlet的service方法;
5.請求結束,放回線程池,等待被調用;
(注意:避免使用實例變量(成員變量),由於若是存在成員變量,可能發生多線程同時訪問該資源時,都來操做它,照成數據的不一致,所以產生線程安全問題)
從上面能夠看出:
第一:Servlet單實例,減小了產生servlet的開銷;
第二:經過線程池來響應多個請求,提升了請求的響應時間;
第三:Servlet容器並不關心到達的Servlet請求訪問的是不是同一個Servlet仍是另外一個Servlet,直接分配給它一個新的線程;若是是同一個Servlet的多個請求,那麼Servlet的service方法將在多線程中併發的執行;
第四:每個請求由ServletRequest對象來接受請求,由ServletResponse對象來響應該請求;
2. Spring
任何Spring Web的entry point,都是servlet。
大名頂頂的spring框架已經風靡多時,一個事物的出現和流行都是會有緣由的,那麼爲何spring 框架會出現呢?緣由就是爲了簡化java開發。
spring的核心就是經過依賴注入、面向切面編程aop、和模版技術,解耦業務與系統服務,消除重複代碼。藉助aop,能夠將遍及應用的關注點(如事物和安全)從它們的應用對象中解耦出來。
Spring 中的Bean
1) POJO和JavaBean的區別 :
"Plain Ordinary Java Object",簡單普通的java對象。主要用來指代那些沒有遵循特定的java對象模型,約定或者框架的對象。
POJO的內在含義是指那些:
有一些private的參數做爲對象的屬性,而後針對每個參數定義get和set方法訪問的接口。
沒有從任何類繼承、也沒有實現任何接口,更沒有被其它框架侵入的java對象。
JavaBean 是一種JAVA語言寫成的可重用組件。JavaBean符合必定規範編寫的Java類,不是一種技術,而是一種規範。你們針對這種規範,總結了不少開發技巧、工具函數。符合這種規範的類,能夠被其它的程序員或者框架使用。它的方法命名,構造及行爲必須符合特定的約定:
全部屬性爲private。
這個類必須有一個公共的缺省構造函數。便是提供無參數的構造器。
這個類的屬性使用getter和setter來訪問,其餘方法聽從標準命名規範。
這個類應是可序列化的。實現serializable接口。
由於這些要求主要是靠約定而不是靠實現接口,因此許多開發者把JavaBean看做聽從特定命名約定的POJO。
spring中,應用對西那個生存於spring容器中,spring 容器建立對象,裝配它們,管理它們的整個生命週期。spring容器經過依賴注入,管理構成應用的組件,它會建立相互協做的組件之間的關聯。
2) Bean的生命週期
Spring MVC
Spring MVC的運行流程: