1、servlet與servlet容器
(1)servlet本質
前方高能,請注意、注意、注意,,,重要的事情說三遍,servlet本質就是一個Java介面 ,目的在于定義一套處理網路請求的規范,如下所示:
package javax.servlet; import java.io.IOException; import javax.servlet.ServletConfig; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletResponse; public interface Servlet { void init(ServletConfig arg0) throws ServletException; ServletConfig getServletConfig(); void service(ServletRequest arg0, ServletResponse arg1) throws ServletException, IOException; String getServletInfo(); void destroy(); }
所有實作servlet介面的類,都要實作介面中的五個方法,其中最主要的是兩個生命周期方法 init()和destroy()、處理請求的service(),即:
- 初始化的作用;
- 銷毀后的作用;
- 收到請求后需要做什么,
init() 和 destroy()方法只執行一次, 即servlet的生命周期---創建和銷毀,而service()方法每次有新請求到達時都會呼叫,即處理處理實際業務,
(2)servlet容器
全稱server applet,意為服務程式,主要作用是給上級容器(Tomcat)提供doGet()和doPost()等方法,其生命周期實體化、初始化、呼叫、銷毀受控于Tomcat容器,
(3)request/response
request:瀏覽器發起http請求,請求到達tomcat,經tomcat封裝成了request物件(將請求頭、請求地址、請求引數等進行了封裝);
response:瀏覽器發起http請求到達tomcat容器時,產生一個空的response物件,http請求資料經過servlet處理,將處理后結果封裝成response物件,經過tomcat處理后,組裝成HTTP回應回傳給瀏覽器,
(4)web容器
可以部署多個WEB應用程式的環境,Tomcat容器屬于web容器的一種,web容器還包括weblogic容器、JBoss容器等;而Tcomcat、webLogic等包含servlet容器,

注:三層架構實質是對servlet的拆分,目的在于解耦合,
2、tomcat
(1)tomcat程式入口main()
main方法是啟動一個java程式的入口,任何程式都會有自己的main方法,tomcat是一個WEB容器,也不例外:
//TODO 以下為偽代碼,目的在于說明tomcat執行原理 public static void main(String args[]) { //TODO 初始化運行環境,載入需要的jar包,讀取conf/server.xml,生成相應的運行物件: if (daemon == null) { Bootstrap bootstrap = new Bootstrap(); try { bootstrap.init();//初始化守護行程 } catch (Throwable t) { return; } daemon = bootstrap; } //TODO 裝載,開始運行, try { String command = "start"; if (command.equals("startd")) { daemon.load(args); daemon.start();//啟動Tomcat } else if (command.equals("stopd")) { args[args.length - 1] = "stop"; daemon.stop();//停止Tomcat守護行程 } } catch (Throwable t) { } }
(2)tomcat創建的resques和response

(3)tomcat對servlet介面的實作
邏輯層級關系:abstract class GenericServlet implements Servlet, ServletConfig,Serializable
abstract class HttpServlet extends GenericServlet
public abstract class HttpServlet extends GenericServlet { protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String protocol = req.getProtocol(); String msg = lStrings.getString("http.method_get_not_supported"); if (protocol.endsWith("1.1")) { resp.sendError(405, msg); } else { resp.sendError(400, msg); } } //TODO doHead doPut doDelete protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String protocol = req.getProtocol(); String msg = lStrings.getString("http.method_post_not_supported"); if (protocol.endsWith("1.1")) { resp.sendError(405, msg); } else { resp.sendError(400, msg); } } protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { String method = req.getMethod(); long errMsg; if (method.equals("GET")) { errMsg = this.getLastModified(req); if (errMsg == -1L) { this.doGet(req, resp); } else { long ifModifiedSince; try { ifModifiedSince = req.getDateHeader("If-Modified-Since"); } catch (IllegalArgumentException arg8) { ifModifiedSince = -1L; } if (ifModifiedSince < errMsg / 1000L * 1000L) { this.maybeSetLastModified(resp, errMsg); this.doGet(req, resp); } else { resp.setStatus(304); } } } else if (method.equals("POST")) { this.doPost(req, resp); } else { String errMsg1 = lStrings.getString("http.method_not_implemented"); Object[] errArgs = new Object[] { method }; errMsg1 = MessageFormat.format(errMsg1, errArgs); resp.sendError(501, errMsg1); } } public void service(ServletRequest req, ServletResponse res) throws ServletException, IOException { HttpServletRequest request; HttpServletResponse response; try { request = (HttpServletRequest) req; response = (HttpServletResponse) res; } catch (ClassCastException arg5) { throw new ServletException(lStrings.getString("http.non_http")); } this.service(request, response); } }
(4)web容器的部署
部署的程序其實就是決議 xml 實體化物件,并觸發和處理容器及組件對應生命周期事件的程序,在 Tomcat 中,一個 Context 實體就代表一個 Web 應用程式,所以部署的第一步就是創建一個 StandardContext 物件,在創建時 HostConfig 首先會查找 Context 描述符,它可能在兩個位置:
- $CATALINA_BASE/conf/<engine>/<host>/[webappname].xml
- $CATALINA_BASE/webapps/webappname/META_INF/context.xml
如果兩個位置都不存在此檔案,則使用 conf/context.xml 默認配置,
Context 實體化后會觸發 init 和 start 生命周期事件:
- init - 會創建用于決議 context.xml 和 web.xml 的工具 Digester 的實體,并決議context.xml
- start - 則會根據 web.xml 部署描述符實體化 Servlet、Filter、Listener 等 Web 組件
感謝閱讀,參考了不少大佬資料,如需轉載,請注明出處 https://www.cnblogs.com/huyangshu-fs/p/13173474.html
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/247045.html
標籤:Java
上一篇:Redis原始碼剖析之robj(redisObject)
下一篇:Java中實作分布式定時任務
