Servlet運行原理 java
Servlet生命週期定義了一個Servlet如何被加載、初始化,以及它怎樣接收請求、響應請求,提供服務。在討論Servlet生命週期以前,先讓咱們來看一下這幾個方法:web
1. init()方法數據庫
在Servlet的生命週期中,僅執行一次init()方法,它是在服務器裝入Servlet時執行的,能夠配置服務器,以在啓動服務器或客戶機首次訪問Servlet時裝入Servlet。不管有多少客戶機訪問Servlet,都不會重複執行init();安全
2. service()方法服務器
它是Servlet的核心,每當一個客戶請求一個HttpServlet對象,該對象的Service()方法就要調用,並且傳遞給這個方法一個「請求」(ServletRequest)對象和一個「響應」(ServletResponse)對象做爲參數。在HttpServlet中已存在Service()方法。默認的服務功能是調用與HTTP請求的方法相應的do功能。網絡
3. destroy()方法多線程
僅執行一次,在服務器端中止且卸載Servlet時執行該方法,有點相似於C++的delete方法。一個Servlet在運行service()方法時可能會產生其餘的線程,所以須要確認在調用destroy()方法時,這些線程已經終止或完成。併發
下面來談談Servlet的生命週期,Servlet的生命週期是由Servlet容器來控制的,它始於裝入Web服務器的內存時,並在終止或從新裝入Servlet時結束。這項操做通常是動態執行的。然而,Server一般會提供一個管理的選項,用於在Server啓動時強制裝載和初始化特定的Servlet。性能
在代碼中,Servlet生命週期由接口javax.servlet.Servlet定義。全部的Java Servlet 必須直接或間接地實現javax.servlet.Servlet接口,這樣才能在Servlet Engine上運行。javax.servlet.Servlet接口定義了一些方法,在Servlet 的生命週期中,這些方法會在特定時間按照必定的順序被調用。.net
Servlet生命週期
加載和實例化Servlet
咱們來看一下Tomcat是如何加載的:
1. 若是已配置自動裝入選項,則在啓動時自動載入。
2. 在服務器啓動時,客戶機首次向Servlet發出請求。
3. 從新裝入Servlet時。
當啓動Servlet容器時,容器首先查找一個配置文件web.xml,這個文件中記錄了能夠提供服務的Servlet。每一個Servlet被指定一個Servlet名,也就是這個Servlet實際對應的Java的完整class文件名。Servlet容器會爲每一個自動裝入選項的Servlet建立一個實例。因此,每一個Servlet類必須有一個公共的無參數的構造器。
初始化
當Servlet被實例化後,Servlet容器將調用每一個Servlet的init方法來實例化每一個實例,執行完init方法以後,Servlet處於「已初始化」狀態。因此說,一旦Servlet被實例化,那麼必將調用init方法。經過Servlet在啓動後不當即初始化,而是收到請求後進行。在web.xml文件中用<load-on-statup> ...... </load-on-statup>對Servlet進行預先初始化。
初始化失敗後,執行init()方法拋出ServletException異常,Servlet對象將會被垃圾回收器回收,當客戶端第一次訪問服務器時加載Servlet實現類,建立對象並執行初始化方法。
請求處理
Servlet 被初始化之後,就處於能響應請求的就緒狀態。每一個對Servlet 的請求由一個Servlet Request 對象表明。Servlet 給客戶端的響應由一個Servlet Response對象表明。對於到達客戶機的請求,服務器建立特定於請求的一個「請求」對象和一個「響應」對象。調用service方法,這個方法能夠調用其餘方法來處理請求。
Service方法會在服務器被訪問時調用,Servlet對象的生命週期中service方法可能被屢次調用,因爲web-server啓動後,服務器中公開的部分資源將處於網絡中,當網絡中的不一樣主機(客戶端)併發訪問服務器中的同一資源,服務器將開設多個線程處理不一樣的請求,多線程同時處理同一對象時,有可能出現數據併發訪問的錯誤。
另外注意,多線程不免同時處理同一變量時(如:對同一文件進行寫操做),且有讀寫操做時,必須考慮是否加上同步,同步添加時,不要添加範圍過大,有可能使程序變爲純粹的單線程,大大削弱了系統性能;只須要作到多個線程安全的訪問相同的對象就能夠了。
卸載Servlet
當服務器再也不須要Servlet實例或從新裝入時,會調用destroy方法,使用這個方法,Servlet能夠釋放掉全部在init方法申請的資源。一個Servlet實例一旦終止,就不容許再次被調用,只能等待被卸載。
Servlet一旦終止,Servlet實例便可被垃圾回收,處於「卸載」狀態,若是Servlet容器被關閉,Servlet也會被卸載,一個Servlet實例只能初始化一次,但能夠建立多個相同的Servlet實例。如相同的Servlet能夠在根據不一樣的配置參數鏈接不一樣的數據庫時建立多個實例。
摘自-fifiyong