1. 程式人生 > >java基礎78 Servlet的生命週期

java基礎78 Servlet的生命週期

1、Servlet的生命週期

簡單的解析就是:

建立servlet例項(呼叫構造器)---->呼叫init()方法---->呼叫service()方法----->呼叫destroy()方法

構造方法:建立servlet時被呼叫,預設情況下,第一次訪問servlet的時,建立servlet物件值只調用一次,證明servlet物件在tomcat是單例項.
init方法:建立玩servlet物件是呼叫。只調用一次
service方法每次傳送請求時被呼叫。呼叫n次(有多少次請求,就呼叫多少次)
destroy方法:銷燬servlet物件時呼叫,只調用一次。(停止伺服器或者重啟伺服器【重新部署web應用】的時候銷燬servlet物件)

1.1、例項

 1 package com.shore.myservlet;
 2 
 3 
 4 import java.io.IOException;
 5 
 6 import javax.servlet.ServletException;
 7 import javax.servlet.http.HttpServlet;
 8 import javax.servlet.http.HttpServletRequest;
 9 import javax.servlet.http.HttpServletResponse;
10 
11 /**
12  * @author DSHORE / 2018-9-14
13 * 14 */ 15 public class MyServletOne extends HttpServlet { 16 //構造方法 17 public MyServletOne() { 18 System.out.println("構造器被呼叫"); 19 } 20 21 //呼叫init()方法,servlet被初始化 22 public void init() throws ServletException { 23 System.out.println("呼叫init方法"); 24 } 25 26
//servlet服務 27 @Override 28 protected void service(HttpServletRequest arg0, HttpServletResponse arg1) 29 throws ServletException, IOException { 30 System.out.println("呼叫service方法"); 31 } 32 //呼叫destroy()方法,servlet被銷燬! 33 public void destroy() { 34 System.out.println("呼叫destroy方法"); 35 //super.destroy(); 36 } 37 }

配置檔案:web.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app version="2.5" 
 3     xmlns="http://java.sun.com/xml/ns/javaee" 
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 6     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
 7   <display-name></display-name>
 8   
 9   <!-- servlet的配置檔案 -->
10   <servlet>
11       <!--servlet內部名稱(類名),可以自定義 -->
12     <servlet-name>MyServletOne</servlet-name>
13     <!-- servlet類名:包名+簡單類名 -->
14     <servlet-class>com.shore.myservlet.MyServletOne</servlet-class>
15   </servlet>
16 
17   <!-- servlet的對映配置 -->
18   <servlet-mapping>
19       <!-- servlet內部名稱(類名),可以自定義,和上面保持一致 --> 
20     <servlet-name>MyServletOne</servlet-name>
21     <!-- servlet訪問名稱:/名稱 -->
22     <url-pattern>/MyServletOne</url-pattern>
23   </servlet-mapping>
24       
25   <welcome-file-list>
26     <welcome-file>index.jsp</welcome-file>
27   </welcome-file-list>
28 </web-app>

結果圖

1.2、Servlet生命週期的業務邏輯過程解析(以上面的例項作為解析案例)

瀏覽器                                                       Tomcat伺服器                                               MyServletOne物件

 (1) 向伺服器傳送請求 http://localhost:8080/MyServlet/MyServletOne(可以看瀏覽器端的請求頭資訊)
 (2) 擷取/MyServlet,進入webapps目錄下的MyServlet目錄。
 (3) 擷取/MyServletOne,去MyServlet下的web.xml檔案中查詢是否有匹配的<url-patten>/MyServletOne</url-patten>
 (4) 如果匹配,則在web.xml檔案中查詢是否有名稱相同的servlet配置。
 (5) 如果找到,則去尋找servlet配置中的servlet-class的內容:com.shore.myservlet.MyServletOne
 (6) 建立MyServletOne物件。
 (7) 呼叫構造方法:public MyServletOne(){.....}
 (8) 構造方法被呼叫,建立ServletConfig物件,呼叫init方法
 (9) init方法被呼叫,建立request、response物件
(10) service被呼叫(service根據頁面傳過來的的請求方式,決定呼叫doGet方法/doPost方法)
(11) 返回被修改的response物件,並且把response物件解析成相應的格式的資料(瀏覽器端的響應頭資訊可以體現)
(12) 如果伺服器停止,則呼叫destroy方法,銷燬本次servlet請求。

附錄

1、servlet的自動載入

    預設情況下,第一次訪問servlet的時候建立servlet物件。如果servlet的構造方法或者init方法中執行比較多的邏輯程式碼,那麼會導致第一次訪問的時候比較慢。
    解決方法:改變servlet建立物件的時機

 1 <!-- servlet的配置檔案 -->
 2   <servlet>
 3       <!--servlet內部名稱(類名),可以自定義 -->
 4     <servlet-name>MyServletOne</servlet-name>
 5     <!-- servlet類名:包名+簡單類名 -->
 6     <servlet-class>com.shore.myservlet.MyServletOne</servlet-class>
 7     <!-- 作用:伺服器一啟動,構造器和init方法就被提前載入 。 注意:整數值越大,建立優先順序越低 -->
 8     <load-on-startup>1</load-on-startup>
 9   </servlet>
10 
11   <!-- servlet的對映配置 -->
12   <servlet-mapping>
13       <!-- servlet內部名稱(類名),可以自定義,和上面保持一致 --> 
14     <servlet-name>MyServletOne</servlet-name>
15     <!-- servlet訪問名稱:/名稱 -->
16     <url-pattern>/MyServletOne</url-pattern>
17   </servlet-mapping>

2、Servlet的多執行緒併發問題

注意:servlet物件在tomcat伺服器是單例項多執行緒
    因為servlet是多執行緒的,所以,當有多個servlet執行緒訪問servlet的共享資料時,如果成員變數(即:全域性變數),可能會引發執行緒安全問題。
解決辦法:
  1)把使用共享的資料程式碼進行同步(synchronized(鎖)關鍵字進行同步)
  2)建議在servlet類中儘量不要使用成員變數。如果確實要使用成員變數,必須同步,而且儘量縮小同步程式碼塊的範圍。(哪裡使用到了成員變數就同步哪裡!),以避免因為同步而導致效率降低

2.1、出現多個執行緒併發的例子

web.xml檔案

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <web-app version="3.0" 
 3     xmlns="http://java.sun.com/xml/ns/javaee" 
 4     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
 5     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
 6     http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
 7   <display-name></display-name>
 8   <servlet>
 9     <servlet-name>MyServlet</servlet-name>
10     <servlet-class>com.shore.mservlet.MyServlet</servlet-class>
11   </servlet>
12 
13   <servlet-mapping>
14     <servlet-name>MyServlet</servlet-name>
15     <url-pattern>/MyServlet</url-pattern>
16   </servlet-mapping>    
17   <welcome-file-list>
18     <welcome-file>index.jsp</welcome-file>
19   </welcome-file-list>
20 </web-app>

MyServlet類 檔案

 1 package com.shore.mservlet;
 2 
 3 import java.io.IOException;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 
 9 /**
10  * @author DSHORE / 2018-9-18
11  *
12  */
13 public class MyServlet extends HttpServlet {
14     int counnt = 1;
15     public void doGet(HttpServletRequest request, HttpServletResponse response)
16             throws ServletException, IOException {
17         response.setCharacterEncoding("GBK");
18         response.getWriter().write("第"+counnt+"次");
19         //睡眠5秒鐘  19到25行程式碼的作用:測試時 更容易看出是否是執行緒併發問題
20         Thread thread = new Thread();
21         try {
22             thread.sleep(5000);
23         } catch (InterruptedException e) {
24             e.printStackTrace();
25         }
26         counnt++;
27     }
28 
29     public void doPost(HttpServletRequest request, HttpServletResponse response)
30             throws ServletException, IOException {
31         doGet(request, response);
32     }
33 }

結果圖

由上圖,可以看出:同時出現了一個“4”,說明出現了執行緒問題;解決方法看下面的例子

2.2、解決多執行緒併發的例子

在MyServlet類中,需要共享的資料,用同步程式碼塊 同步掉,即可。

 1 package com.shore.mservlet;
 2 
 3 import java.io.IOException;
 4 import javax.servlet.ServletException;
 5 import javax.servlet.http.HttpServlet;
 6 import javax.servlet.http.HttpServletRequest;
 7 import javax.servlet.http.HttpServletResponse;
 8 
 9 /**
10  * @author DSHORE / 2018-9-18
11  *
12  */
13 public class MyServlet extends HttpServlet {
14     int counnt = 1;
15     public void doGet(HttpServletRequest request, HttpServletResponse response)
16             throws ServletException, IOException {
17         response.setCharacterEncoding("GBK");
18         synchronized (MyServlet.class) {//MyServlet.class是惟一的
19             response.getWriter().write("第"+counnt+"次");
20             counnt++;
21         }
22     }
23 
24     public void doPost(HttpServletRequest request, HttpServletResponse response)
25             throws ServletException, IOException {
26         doGet(request, response);
27     }
28 }

結果圖

就算有很多個人,同時訪問 也不會出現重複的數字(即:不會出現執行緒安全問題)

3、Servlet程式設計知識點

1) servlet生命週期

構造方法:建立servlet物件,預設情況下,第一次訪問servlet物件時,值呼叫一次。
init方法(有參):建立servlet物件後呼叫,只調用一次。 注意:會呼叫無參的init方法
service方法:service提供服務的方法,每次方式請求呼叫。注意:request物件,response物件
destroy方法:tomcat停止或者web應用重新部署,servlet物件銷燬,destroy方法被呼叫。

2)servletConfig物件

    獲取servlet的初始化引數:
        getInitParameter(“name”);
        getInitParameterNames();

3)servletContext物件

    得到web應用路徑:
          Context.getContextPath();
          Request.getContextPath();
    得到web應用的引數:
          context.getInitParameter(“name”);
          context.getInitParameterNames();
    域物件:
          Context.setAttribute(“name”,objext); //儲存資料
          Context.getAttribute(“name”); //得到資料
          Context.removeAttribute(“name”); //清除資料
    轉發:
          Context.getRequestDispatcher(“路徑”).forward(request,response);
          Request. getRequestDispatcher(“路徑”).forward(request,response);
    得到web應用的資源:
          Context.getRealPath(“路徑”);
          Context.getResourceAsStream(“路徑”);

相關推薦

java基礎78 Servlet生命週期

1、Servlet的生命週期 簡單的解析就是: 建立servlet例項(呼叫構造器)---->呼叫init()方法---->呼叫service()方法----->呼叫destroy()方法 構造方法:建立servlet時被呼叫,預設情況下,第一次訪問servlet的時,建立servlet物

Java開發之Servlet生命週期

     Servlet會在伺服器啟動或第一次請求該Servlet的時候開始生命週期,在伺服器結束的時候結束生命週期。無論請求多少次Servlet,最多隻有一個Servlet例項。多個客戶端併發請求Se

Java Web的生命週期Servlet生命週期

Java Web的生命週期與Servlet生命週期 1.Web應用:3階段,啟動階段、執行階段、終止階段 a) 啟動:載入web.xml--------為web應用建立一個ServletContext物件-----初始化所有Filter-----對需要啟動時就要初始化的Servlet

Java面試經典:Servlet生命週期

  只存在一個Servlet物件,在有客戶端請求時才進行初始化,也只初始化一次,在destroy之前,所有的請求不再初始化。初始化完成後呼叫init方法,同初始化一樣,init方法也只調用一次。接下來對於每個請求先呼叫公有的service方法,然後公有的service方法再呼叫私有的service方法,私有的

Java併發基礎Java執行緒的生命週期

前言 執行緒是作業系統中的一個概念,支援多執行緒的語言都是對OS中的執行緒進行了封裝。要學好執行緒,就要搞清除它的生命週期,也就是生命週期各個節點的狀態轉換機制。不同的開發語言對作業系統中的執行緒進行了不同的封裝,但是對於執行緒的宣告週期這部分基本是相同的。下面先介紹通用的執行緒生命週期模型,然後詳細介紹Ja

JAVA基礎篇—Servlet小結

組件 一個 另一個 操作 默認 list 變化 nbsp tor 一、get請求和post請求的區別: 1.get請求是通過url傳遞參數,post請求是通過請求體傳遞參數的 2.get請求最多允許傳遞255個字符,對長度有限制,所以數據比較大的時候我們使用post請求

java web】Servlet生命周期

控制臺顯示 encoding port protect err 我們 sys 技術 vax 在Java web中 Servlet 是根基。雖然工作中幾乎沒人再去寫Servlet了,框架為我們完成了這些工作。我們只要專註於業務邏輯的實現。但是理解Servlet還是很有必要的。

Java多執行緒生命週期

關於Java中執行緒的生命週期,首先看一下下面這張較為經典的圖: 上圖中基本上囊括了Java中多執行緒各重要知識點。掌握了上圖中的各知識點,Java中的多執行緒也就基本上掌握了。主要包括: Java執行緒具有五中基本狀態 新建狀態(New):當執行緒物件對建立後,即進入了

JAVA執行緒的生命週期和分析工具

執行緒的生命週期的六種狀態  其中一種 有效的方法就是看原始碼 1、NEW 在 虛擬機器的 中建立物件,初始化 成員變數。 2、RUNNABLE 在虛擬中建立執行緒 私有的程式計數器,虛擬機器棧, 等待虛擬機器 執行緒排程器,分配時間片。 3、BLOCKED

Gradle基礎:3:生命週期管理

Maven中的生命週期的管理使用了COC,以此為中心的pom.xml檔案成為了重中之重,優點是不同專案之間的經驗共享變得更加容易,大家大部分都是可以使用類似的套路,缺點則是靈活性稍微降低以及對於pom.xml細節的學習需要較多時間。Gradle則將這些再次放開,給更多的許可權與開發者,這

Java執行緒的生命週期小結

Java執行緒的狀態轉換 1.1新建狀態(New) 用new語句建立的執行緒處於新建狀態,此時它和其他Java物件一樣,僅僅在堆區中被分配了記憶體。 1.2就緒狀態(Runnable) 當一個執行緒物件建立後,其他執行緒呼叫它的start()方法,該執行緒就進入就緒

Servlet入門(四)Servlet生命週期

前言        通過前面的講解,我們基本瞭解了Servlet的作用和流程,本章探討Servlet的生命週期 方法 1.概念 在學習本章之前,我們先來回顧一下Servlet的執行流程: 瀏覽器傳送請求至伺服器 伺服器根據根

servlet生命週期和執行流程

一 、生命週期 servlet 宣告週期可以分四個階段: 類裝載過程 init() 初始化過程 service() 服務過程,選擇doGet \ doPost destroy() 銷燬過程 servlet介面如下 public interface Servlet {

Servlet生命週期理解

Servlet生命週期說的便是Servlet從誕生直至消亡的整個過程。 Servlet生命週期分為四個階段: (一)初始化 init() 在Servlet的整個生命週期中 初始化inti()方法 只會被呼叫一次, 之後無論多少次請求都不會再執行init(

利用Nomad構建彈性基礎設施: 工作生命週期

SEP 13 2018 CHRISTIE KOEHLER This is the third in a series Building Resilient Infrastructure with Nomad (Part 1, Part 2). In this series

Servlet生命週期、常用提交方式、中文亂碼問題、重定向和請求轉發

//當前工作空間絕對路徑System.getProperty("user.dir"); 一個Servlet的生命週期由 例項化,初始化,提供服務,銷燬,被回收 幾個步驟組成Serlvet構造方法 只會執行一次,所以Serlvet是單例項的init初始化 只會執行一次     &

Servlet生命週期

Servlet部署在容器裡,它的生命週期由容器管理。Servlet的生命週期概括為以下幾個階段。 (1)當Web客戶請求Servlet服務或當Web服務啟動時,容器環境載入一個Java Servlet類。 (2)容器環境也將根據客戶請求建立一個Servlet物件例項,或者

Java執行緒的生命週期

Java多執行緒程式設計 Java給多執行緒提供了內建的支援。一條執行緒指的是程序中一個單一順序的控制流,一個程序中可以併發存在多個執行緒,每條執行緒並行執行不同的任務。多執行緒是多工的一種特別形式。 程序:一個程序包括有作業系統分配的記憶體空間,包含至少一個執行緒。一個

使用Nomad構建彈性基礎架構: 工作生命週期

這是Nomad構建彈性基礎架構系列(第1部分,第2部分)中的第三部分。在本系列中,我們將探討Nomad如何處理意外故障、停機和叢集基礎架構的日常維護,通常不需要操作員干預。 在本文中,我們將介紹Nomad如何通過提供一個一致的工作流來管理整個作業生命週期,從而為您的計算基礎

06-碼蟻JavaWeb之Servlet生命週期與基本配置

學習地址:[撩課-JavaWeb系列1之基礎語法-前端基礎](https://study.163.com/course/introduction/1005537028.htm)[撩課-JavaWeb系列2之XML](https://study.163.com/course/introduction/10059