畫的不好,請將就。。。。

我一般用的IDEA,很久沒用Eclipse了,所以剛開始怎麼繼承不了HttpServlet類,然後看了一眼我創建的是Maven項目,然後去Maven倉庫粘貼了,Servlet的坐標進來。

maven坐標獲取,直接百度maven倉庫,選擇第二個。

然後搜索Servlet選擇第二個。

創建一個類,不是介面,繼承下HttpServlet。

Servlet 介面 :

public interface Servlet {

//負責初始化 Servlet 對象。容器一旦創建好 Servlet 對象後,就調用此方法來初始化 Servlet 對象。 public void init(ServletConfig config) throws ServletException; //負責處理客戶的請求並返迴響應。當容器接收到客戶端要求訪問特定的 servlet 請 求時,就會調用 Servlet 的 service 方法 。

public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException;

//Destroy()方法負責釋放 Servlet 對象佔用的資源,當 servlet 對象結束生命週期時, servlet 容器調用此方法來銷毀 servlet 對象。 public void destroy();

//說明:Init(),service(),destroy() 這三個方法是 Servlet 生命週期中的最重要的三個方法。

//返回一個字元串,在該字元串中包含 servlet 的創建者,版本和版權等信息 public String getServletInfo();

//GetServletConfig: 返回一個 ServletConfig 對象,該對象中包含了 Servlet 初始化參 數信息

public ServletConfig getServletConfig(); }

init 方法接收一個 ServletConfig 參數,由容器傳入.ServletConfig 就是 Servlet 的配置,在 web.xml 中定義 Servlet 時通過 init-param 標籤配置的參數由 ServletConfig 保存


ServletConfig 介面

public interface ServletConfig {

//用於獲取 Servlet 名,web.xml 中定義的 servlet-name String getServletName(); //獲取 Servlet 上下文對象(非常重要) ServletContext getServletContext(); //獲取 init-param 中的配置參數 String getInitParameter(String var1); //獲取配置的所有 init-param 名字集合 Enumeration<String> getInitParameterNames();

}

ServletConfig 是 Servlet 級別,而 ServletContext 是全局的


GenericServlet 抽象類

GenericServlet 是 Servlet 的默認實現,是與具體協議無關的

//抽象類 GenericServlet 實現了 Servlet 介面的同時,也實現了 ServletConfig 介面和 Serializable 這兩個介面

public abstract class GenericServlet

implements Servlet, ServletConfig, java.io.Serializable

{ //私有變數,保存 init()傳入的 ServletConfig 對象的引用 private transient ServletConfig config; //無參的構造方法 public GenericServlet() { } ------------------------------------ 以下方法實現了 servlet 介面中的 5 個方法 實現 Servlet 介面方法開始 ------------------------------------ /*

實現介面 Servlet 中的帶參數的 init(ServletConfig Config)方法,將傳遞的

ServletConfig 對象的引用保存到私有成員變數中, 使得 GenericServlet 對象和一個 ServletConfig 對象關聯. 同時它也調用了自身的不帶參數的 init()方法

**/

public void init(ServletConfig config) throws ServletException { this.config = config;

this.init(); //調用了無參的 init()方法 } //無參的 init()方法 public void init() throws ServletException { } //空實現了 destroy 方法 public void destroy() { } //實現了介面中的 getServletConfig 方法,返回 ServletConfig 對象 public ServletConfig getServletConfig() {

return config; }

//該方法實現介面<Servlet>中的 ServletInfo,默認返回空字元串 public String getServletInfo() { return ""; } //唯一沒有實現的抽象方法 service(),僅僅在此聲明。交由子類去實現具體的應用 //在後來的 HttpServlet 抽象類中,針對當前基於 Http 協議的 Web 開發,HttpServlet 抽象類具體實現了這個方法 //若有其他的協議,直接繼承本類後實現相關協議即可,具有很強的擴展性 public abstract void service(ServletRequest req, ServletResponse res) throws IOException; ------------------------------------ 實現 Servlet 介面方法結束 ------------------------------------

--------------------------------------------- 以下四個方法實現了介面 ServletConfig 中的方法 實現 ServletConfig 介面開始

--------------------------------------------- ServletException, //該方法實現了介面<ServletConfig>中的 getServletContext 方法,用於返回 servleConfig 對象中所包含的 servletContext 方法 public ServletContext getServletContext() { return getServletConfig().getServletContext(); }

//獲取初始化參數

public String getInitParameter(String name) { return getServletConfig().getInitParameter(name); } //實現了介面<ServletConfig>中的方法,用於返回在 web.xml 文件中為 servlet 所配 置的全部的初始化參數的值 public Enumeration getInitParameterNames() { return getServletConfig().getInitParameterNames(); //獲取在 web.xml 文件中註冊的當前的這個 servlet 名稱。沒有在 web.xml 中註冊的 servlet,該方法直接放回該 servlet 的類名。 //法實現了介面<ServleConfig>中的 getServletName 方法 public String getServletName() { return config.getServletName(); } --------------------------------------------- 實現 ServletConfig 介面結束 --------------------------------------------- public void log(String msg) { getServletContext().log(getServletName() + ": "+ msg); } public void log(String message, Throwable t) { getServletContext().log(getServletName() + ": " + message, t); } }

還有最底層的HttpServlet,這個就不說了,說下Tomcat的底層源碼。


Server

Server 伺服器的意思,代表整個 tomcat 伺服器,一個 tomcat 只有一個 Server Server 中包含至少一個 Service 組件,用於提供具體服務。這個在配置文件中也得到很 好的體現(port=「8005」 shutdown="SHUTDOWN"是在 8005 埠監聽到"SHUTDOWN"命 令,伺服器就會停止)

Service

Service 中的一個邏輯功能層, 一個 Server 可以包含多個 Service Service 接收客戶端的請求,然後解析請求,完成相應的業務邏輯,然後把處理後的結 果返回給客戶端,一般會提供兩個方法,一個 start 打開服務 Socket 連接,監聽服務埠, 一個 stop 停止服務釋放網路資源。

Connector

稱作連接器,是 Service 的核心組件之一,一個 Service 可以有多個 Connector,主要是 連接客戶端請求,用於接受請求並將請求封裝成 Request 和 Response,然後交給 Container 進 行處理,Container 處理完之後在交給 Connector 返回給客戶端。

Container

Service 的另一個核心組件,按照層級有 Engine,Host,Context,Wrapper 四種,一個 Service 只有一個 Engine,其主要作用是執行業務邏輯

Engine

一個 Service 中有多個 Connector 和一個 Engine,Engine 表示整個 Servlet 引擎,一個 Engine 下面可以包含一個或者多個 Host,即一個 Tomcat 實例可以配置多個虛擬主機,默認 的情況下 conf/server.xml 配置文件中<Engine name="Catalina" defaultHost="localhost"> 定 義了一個名為 Catalina 的 Engine。 一個 Engine 包含多個 Host 的設計,使得一個伺服器實例可以承擔多個域名的服務 1.6 Host 代表一個站點,也可以叫虛擬主機,一個 Host 可以配置多個 Context,在 server.xml 文 件 中 的 默 認 配 置 為 <Host name="localhost" appBase="webapps" unpackWARs="true" autoDeploy="true">, 其中 appBase=webapps, 也就是<CATALINA_HOME>webapps 目錄, unpackingWARS=true 屬性指定在 appBase 指定的目錄中的 war 包都自動的解壓, autoDeploy=true 屬性指定對加入到 appBase 目錄的 war 包進行自動的部署。

Context Context,代表一個應用程序,就是日常開發中的 web 程序,或者一個 WEB-INF 目錄以 及下面的 web.xml 文件,換句話說每一個運行的 webapp 最終都是以 Context 的形式存在, 每個 Context 都有一個根路徑和請求路徑;與 Host 的區別是 Context 代表一個應用,如,默 認配置下 webapps 下的每個目錄都是一個應用,其中 ROOT 目錄中存放主應用,其他目錄 存放別的子應用,而整個 webapps 是一個站點。

Tomcat的啟動流程

tomcat 的啟動流程很標準化,入口是 BootStrap,統一按照生命週期管理介面 Lifecycle 的定義進行啟動。首先,調用 init()方法逐級初始化,接著調用 start()方法進行啟動,同時, 每次調用伴隨著生命週期狀態變更事件的觸發。

啟動文件分析 Startup.bat

catalina.bat set "CLASSPATH=%CLASSPATH%%CATALINA_HOME%inootstrap.jar" set MAINCLASS=org.apache.catalina.startup.Bootstrap set ACTION=start

Bootstrap

main 方法是整個 tomcat 啟動時的入口。在 main 方法中,使用 bootstrap.init()來初始化 類載入器和創建 Catalina 實例,然後再啟動 Catalina 線程

bootstrap.init()方法 用於初始化容器相關,首先創建類載入器,然後通過反射創建 org.apache.catalina.startup.Catalina 實例。

Catalina

Lifecycle 介面Lifecycle 提供一種統一的管理對象生命週期的介面。通過 Lifecycle、LifecycleListener、

LifecycleEvent

Catalina 實現了對 tomcat 各種組件、容器統一的啟動和停止的方式。

在 Tomcat 服務開啟過程中啟動的一些列組件、容器,都實現org.apache.catalina.Lifecycle 這個介面,其中的 init()、start() 方法、stop() 方法,為其子類實現了統一的 start 和 stop 管理。

load 方法解析

server.xml 配置文件:

並載入 Server、Service、Connector、Container、Engine、 Host、Context、Wrapper 一系列的容器,載入完成後,調用 initialize()來開啟一個新的 Server

Digester 類:

解析 server.xml 文件

demon.start() demon.start()方法會調用 Catalina 的 start 方法 Catalina 實例執行 start 方法。這裡有兩個點,一個是 load()載入 server.xml 配置、初始 化 Server 的過程,一個是 getServer().start()開啟服務、初始化並開啟一系列組件、子容器的 過程

StandardServer

service.initialize()

然後拿到 StandardServer 實例調用 initialize()方法初始化 Tomcat 容器的一系列組件。一 些容器初始化的的時候,都會調用其子容器的 initialize()方法,初始化它的子容器。順序是 StandardServer、StandardService、StandardEngine、Connector。每個容器都在初始化自身相 關設置的同時,將子容器初始化。
推薦閱讀:
相關文章