Servlet規(guī)范和Servlet容器
由HTTP請求過程可以知道,HTTP服務(wù)器收到請求后,需要調(diào)用服務(wù)端程序進行處理,所謂的服務(wù)端程序就是開發(fā)人員編寫的Java類,一般來說不同的請求需要由不同的Java類進行處理,而HTTP并不知道要調(diào)用哪個Java類的哪個方法,所以就有了Servlet接口.
雖然有了Servlet接口,將具體實現(xiàn)交由業(yè)務(wù)方處理,但是對于特定的請求,HTTP服務(wù)器是無法知道由哪個Servlet進行處理的,所有又有了Servlet容器,Servlet容器用來加載和管理業(yè)務(wù)類.將HTTP請求交由Servlet容器去處理,容器根據(jù)請求轉(zhuǎn)發(fā)到具體的Servlet,如果Servlet沒有創(chuàng)建則進行實例化,然后調(diào)用這個Servlet的接口方法.Servlet接口其實是Servlet容器跟具體業(yè)務(wù)類之間的接口
可以看到Tomcat通過Servlet容器將HTTP請求具體的業(yè)務(wù)處理進行了解耦,容器通過Servlet接口調(diào)用業(yè)務(wù)類.而Servlet接口和Servlet容器這一套規(guī)范就做Servlet規(guī)范.
Tomcat和Jetty都按照Servlet規(guī)范的要求實現(xiàn)了Servlet容器,同時它們也具備HTTP服務(wù)器的功能.
Servlet接口
javax.servlet.Servlet5個方法
public interface Servlet {
void init(ServletConfig config) throws ServletException;
ServletConfig getServletConfig();
void service(ServletRequest req, ServletResponse res)throws ServletException, IOException;
String getServletInfo();
void destroy();
}
其中最重要的是service方法,具體業(yè)務(wù)類在這個方法里面實現(xiàn)邏輯處理.這個方法的兩個參數(shù)ServletRequest和ServletResponse,其中ServletRequest用來封裝請求信息,ServletResponse用來封裝響應(yīng)信息.本質(zhì)上這兩個類是對通信協(xié)議的封裝.
SpringMVC中的DispatcherServlet在init方法創(chuàng)建了自己的Spring容器.
Servlet容器
Servlet容器主要關(guān)注兩個內(nèi)容
- Web應(yīng)用的目錄格式是什么樣的
- 如何擴展和定制化Servlet容器的功能
工作流程
- 1.HTTP服務(wù)器將請求封裝成ServletRequest對象,調(diào)用
service方法 - 2.根據(jù)請求的URL和Servlet的映射關(guān)系,找到相應(yīng)的Servlet
- 3.如果Servlet沒有被加載,利用反射機制進行創(chuàng)建,并調(diào)用init方法完成初始化,然后再調(diào)用
service方法處理請求 -
4.將響應(yīng)內(nèi)容封裝成ServletResponse對象返回給HTTP服務(wù)器,將響應(yīng)發(fā)送給客戶端
Servlet工作流程
Web應(yīng)用
Servlet容器會實例化和調(diào)用Servlet,一般來說,我們會以Web應(yīng)用程序的方式部署Servlet,根據(jù)Servlet規(guī)范,Web應(yīng)用程序有一定的目錄結(jié)構(gòu),這個目錄結(jié)構(gòu)下分別放置了Servlet類文件,配置文件,靜態(tài)資源,Servlet容器通過讀取配置文件,就能找到Servlet.
Web應(yīng)用的目錄結(jié)構(gòu)
|- WebApp
|- WEB-INF/web.xml --配置文件,用來配置Servlet
|- WEB-INF/lib/ --存放Web應(yīng)用的各種Jar包
|- WEB-INF/classes/ --存放應(yīng)用類,Servlet類
|- META-INF/ --存放工程的信息
Servlet規(guī)范定義了ServletContext接口對應(yīng)Web應(yīng)用.Web應(yīng)用部署好之后,Servlet容器會在啟動時加載Web應(yīng)用,并為Web應(yīng)用創(chuàng)建唯一的ServletContext對象.
一個應(yīng)用只有一個ServletContext,有多個Servlet,Servlet可以通過ServletContext共享數(shù)據(jù).由ServletContext持有所有的Servlet實例
擴展機制
Filter&Listener
Filter是過濾器,可以通過過濾器對請求和響應(yīng)做定制化處理,例如可以根據(jù)請求的頻率限制訪問,根據(jù)國家地區(qū)不同修改響應(yīng)內(nèi)容.
Filter的工作原理
Servlet容器把所有Filter鏈接成一個FilterChain,當請求進來之后,獲取第一個Filter并調(diào)用
doFilter方法,doFilter方法負責調(diào)用FilterChain的下一個方法.這里用到了責任鏈模式
Listener監(jiān)聽器,當應(yīng)用在Servlet容器中運行時,Servlet容器內(nèi)部會不斷發(fā)生各種事情,如Web應(yīng)用的啟動,停止,用戶請求到達等.
Spring實現(xiàn)了自己的監(jiān)聽器,用來監(jiān)聽ServletContext的啟動事件,目的是當Servlet容器啟動時,創(chuàng)建并初始化全局的Spring容器.
Filter和Listener的本質(zhì)區(qū)別
- Filter是干預過程的,是過程的一部分,基于過程行為
- Listenr基于狀態(tài),任何行為改變同一個狀態(tài),觸發(fā)的事件是一致的.