JavaWeb Servlet生命周期細枝末節(jié)處深究
生命周期速覽
優(yōu)先級
servlet 的聲明周期由 tomcat 服務器自行管轄,程序員無法插手;
只要沒有通過 url 訪問 servlet,那他就永遠不會先行實例化;
除非我們通過在 web.xml 的 servlet 標簽下加上以下標簽,即可立即實例化:
</load-on-startup/>
該標簽內(nèi)也可以填寫整數(shù),整數(shù)越小表示優(yōu)先級越高:
<load-on-startup>1</load-on-startup>
servlet生命周期完整過程
默認情況,服務器啟動后 servlet 對象不會立刻初始化
當用戶發(fā)送第一次請求時:
- 執(zhí)行 servlet 無參構造
- tomcat 調(diào)用 servlet 的 init 方法
- tomcat 繼續(xù)調(diào)用 service 方法
當用戶第二次乃至之后多次請求時:
因為 servlet 是單例的,所以不會再實例化新的 servlet 對象;
即 init 方法僅執(zhí)行一次,而 service 會在每次調(diào)用時執(zhí)行一次;
servlet 所有核心方法解析
無參構造方法
首次實例化 servlet 的時候第一個調(diào)用的構造方法!
每個 servlet 都必須有一個無參構造方法,且不能存在有參構造方法?。?!
servlet 規(guī)定,不建議隨意增刪構造方法!
init
init 僅會在首次實例化 servlet 的時候執(zhí)行一次;
service
處理用戶請求的方法;
每次調(diào)用 servlet 都會執(zhí)行一次;
destroy
servlet 銷毀前(注意是銷毀前?。。。﹫?zhí)行的方法;
僅執(zhí)行一次
適配器模式去除冗余接口
因為在一個 servlet 中,最常用的接口實際上就只有 init 和 service 倆,故需要隱去其他不常用的接口來保證代碼的整潔度;
解決方式:構造一個通用的抽象類 NormalServlet,并設置僅 service 為抽象方法,此時所有繼承該抽象類的子類就近需要實現(xiàn)唯一的 service 抽象方法了!
代碼清單:NormalServlet.java
package com.zhiyiyi.javaweb.servlet; import jakarta.servlet.*; import java.io.IOException; // 請注意此類為抽象類 public abstract class NormalServlet implements Servlet { @Override public void init(ServletConfig servletConfig) throws ServletException { } @Override public ServletConfig getServletConfig() { return null; } // 僅設置service方法為一個抽象方法 @Override public abstract void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException; @Override public String getServletInfo() { return null; } @Override public void destroy() { } }
代碼清單:CServlet.java
package com.zhiyiyi.javaweb.servlet; import jakarta.servlet.ServletException; import jakarta.servlet.ServletRequest; import jakarta.servlet.ServletResponse; import java.io.IOException; public class CServlet extends NormalServlet{ // 可見,目前就近需要實現(xiàn)唯一的service了,代碼簡潔了許多!?。? @Override public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { } }
這還沒完,我們需要再次對 NormalServlet
進行些許優(yōu)化,好讓子類能夠獲取父類的 ServletConfig
對象
首先聲明一個私有的 ServletConfig 對象,之后于 init 方法內(nèi)進行實例化;
之后子類就可以通過調(diào)用父類中的 getServletConfig
方法來獲取 ServletConfig 對象了?。?!
private ServletConfig config; @Override public void init(ServletConfig servletConfig) throws ServletException { this.config = servletConfig; } @Override public ServletConfig getServletConfig() { return config; }
GenericServlet.java
這個玩意是 servlet 提供的官方版本,用來替換我們剛剛編寫的 NormalServlet 的;
它的功能更加齊全,且能應對子類需要重寫 init 方法的需求;
以后我們編寫 servlet 只需要繼承 GenericServlet
就好了;
到此這篇關于JavaWeb Servlet生命周期細枝末節(jié)處深究的文章就介紹到這了,更多相關JavaWeb Servlet 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
scala 隱式轉(zhuǎn)換與隱式參數(shù)的使用方法
這篇文章主要介紹了scala 隱式轉(zhuǎn)換與隱式參數(shù)的使用方法,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-11-11MyBatis傳入多個參數(shù)時parameterType的寫法
這篇文章主要介紹了MyBatis傳入多個參數(shù)時parameterType的寫法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12Springboot下RedisTemplate的兩種序列化方式實例詳解
這篇文章主要介紹了Springboot下RedisTemplate的兩種序列化方式,通過定義一個配置類,自定義RedisTemplate的序列化方式,結(jié)合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2022-09-09Springboot公共字段填充及ThreadLocal模塊改進方案
這篇文章主要為大家介紹了Springboot公共字段填充及ThreadLocal模塊改進方案詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-11-11