對於Servlet,服務器只建立每一個servlet的單一實例,每一個用戶請求都會引起新的線程-----將用戶請求將會給相應的doGet/doPost進行處理。那麼,servlet是如何進行建立和銷燬的? web
當首次建立servlet時,它的init方法會獲得調用,在這以前首先是服務器加載相應的servlet。init是放置一次性代碼 的地方,在這以後,針對每一個用戶請求,都會建立一個線程,該線程調用前面建立的實例的service方法。多個併發請求通常會致使多個線程的同時調用 service(儘管能夠實現特殊的接口,如 SingleThreadModel,規定任什麼時候間只容許單個線程運行)。在調用service方法後,根據service方法收到的HTTP請求的類型,調用doGet,doPost,若其餘doXxx方法,最後,若是服務決定缷載某個service,它會首先調用servlet的destroy方法。 數據庫
service方法 服務器
服務器每次接收到對servlet的請求,都會產生一個新的線程,調用service方法,service方法檢查HTTP請求的類型(GET,POST,PUT,DELETE等)並相應地調用doGet,doPost,doPut,doDelete等方法,GET請求原由於正常的URL請求,或沒有指定method="post"的表單請求。POST請求原由於特別將POST列爲method的HTML表單,其餘HTTP請求都由定製客戶生成。 cookie
若是咱們須要在servlet中等同地處理POST和GET請求,咱們有可能會不去實現doPost doGet方法,而是直接配覆寫service方法。可是這樣作不是一個好的思想,咱們應該在doPost方法中調用doGet或相反。 多線程
public void doPost(HttpServletRequest request,HttpServletResponse response)throws ServletException,IOException{ 併發
doGet(request,response); post
} spa
public void doGet()throws ServletException,IOException{ // 相應的業務處理方法代碼 線程
} 接口
這樣作有幾處優勢:首先,咱們還能夠添加doPut,doTrace等方法,支持HTTP請求方法;其次,能夠經過添加getLastModified方法加入對修改日期的支持。
destroy方法
服務器能夠會決定移除以前載入的servlet實例,這時候它會調用servlet的destroy方法,從而使得servlet有機會關閉數據庫鏈接、中止後臺運行的線程、將cookie列表和點擊計數寫入到磁盤,並執行其餘清理活動。在這裏,要注意的是 web服務器可能會崩潰;因此咱們不該該將destory機制做爲向磁盤上保存狀態的唯一機制。若是服務器執行諸如點擊計數,或對cookie值(表示特殊的訪問 )的列表進行累加等活動,應該主動地按期將數據寫到磁盤上。
Servlet 與CGI的區別:
與CGI的區別在於servlet處於服務器進程中,它經過多線程方式運行其service方法,一個實例能夠服務於多個請求,而且其實例通常不會銷燬,而CGI對每一個請求都產生新的進程,服務完成後就銷燬,因此效率上低於servlet。