網(wǎng)上購物系統(tǒng)源代碼/關(guān)鍵詞優(yōu)化建議
2023.10.18
????????WEB容器創(chuàng)建的Servlet對象,這些Servlet對象都會(huì)被放到一個(gè)集合當(dāng)中(HashMap),這個(gè)集合當(dāng)中存儲(chǔ)了Servlet對象和請求路徑之間的關(guān)系 。只有放到這個(gè)HashMap集合中的Servlet才能夠被WEB容器管理,自己new的Servlet對象不會(huì)被WEB容器管理。
????????默認(rèn)情況下,服務(wù)器在啟動(dòng)的時(shí)候Servlet對象并不會(huì)被實(shí)例化。這一點(diǎn)可以在Servlet中提供一個(gè)無參數(shù)的構(gòu)造方法,啟動(dòng)服務(wù)器的時(shí)候看一下構(gòu)造方法是否執(zhí)行,測試結(jié)果發(fā)現(xiàn)不會(huì)執(zhí)行。這個(gè)設(shè)計(jì)也是合理的。用戶沒有發(fā)送請求之前,如果提前創(chuàng)建出來所有的Servlet對象,將耗費(fèi)大量內(nèi)存的,并且創(chuàng)建出來的Servlet如果一直沒有用戶訪問,顯然這個(gè)Servlet對象是一個(gè)廢物,沒必要先創(chuàng)建。
? ? ? ? 也可以手動(dòng)讓服務(wù)器啟動(dòng)的時(shí)候創(chuàng)建servlet對象,只需要在web.xml中添加<load-on-startup>子標(biāo)簽,在該子標(biāo)簽中填寫整數(shù),越小的整數(shù)優(yōu)先級(jí)越高。
<servlet><servlet-name>aservlet</servlet-name><servlet-class>com.servlet.Aservlet</servlet-class><load-on-startup>3</load-on-startup></servlet><servlet-mapping><servlet-name>aservlet</servlet-name><url-pattern>/a</url-pattern></servlet-mapping>
? ? ? ? ?這里編寫一個(gè)servlet程序,測試一下方法的調(diào)用情況:
package com.servlet;import jakarta.servlet.*;import java.io.IOException;public class Aservlet implements Servlet {public Aservlet() {System.out.println("Aservlet的無參數(shù)構(gòu)造方法執(zhí)行");}@Overridepublic void init(ServletConfig servletConfig) throws ServletException {System.out.println("Aservlet's init method execute!");}@Overridepublic ServletConfig getServletConfig() {return null;}@Overridepublic void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {System.out.println("Aservlet's service method execute!");}@Overridepublic String getServletInfo() {return null;}@Overridepublic void destroy() {System.out.println("Aservlet's destroy method execute!");}
}
????????用戶在發(fā)送第一次請求的時(shí)候,控制臺(tái)將輸出以下內(nèi)容:
?
-
根據(jù)以上輸出內(nèi)容得出結(jié)論:
-
用戶在發(fā)送第一次請求的時(shí)候Servlet對象被實(shí)例化(AServlet的構(gòu)造方法被執(zhí)行了。并且執(zhí)行的是無參數(shù)構(gòu)造方法。)
-
AServlet對象被創(chuàng)建出來之后,Tomcat服務(wù)器馬上調(diào)用了AServlet對象的init方法。(init方法在執(zhí)行的時(shí)候,AServlet對象已經(jīng)存在了。已經(jīng)被創(chuàng)建出來了。)
-
用戶發(fā)送第一次請求的時(shí)候,init方法執(zhí)行之后,Tomcat服務(wù)器馬上調(diào)用AServlet對象的service方法。
-
????????用戶繼續(xù)發(fā)送第二次、第三次、第四次請求,控制臺(tái)輸出了以下內(nèi)容:
-
根據(jù)以上輸出結(jié)果得知,用戶在發(fā)送第二次,或者第三次,或者第四次請求的時(shí)候,Servlet對象并沒有新建,還是使用之前創(chuàng)建好的Servlet對象,直接調(diào)用該Servlet對象的service方法,這說明:
-
第一:Servlet對象是單例的(單實(shí)例的。但是要注意:Servlet對象是單實(shí)例的,但是Servlet類并不符合單例模式。我們稱之為假單例。之所以單例是因?yàn)镾ervlet對象的創(chuàng)建我們javaweb程序員管不著,這個(gè)對象的創(chuàng)建只能是Tomcat來說了算,Tomcat只創(chuàng)建了一個(gè),所以導(dǎo)致了單例,但是屬于假單例。真單例模式,構(gòu)造方法是私有化的。)
-
第二:無參數(shù)構(gòu)造方法、init方法只在第一次用戶發(fā)送請求的時(shí)候執(zhí)行。也就是說無參數(shù)構(gòu)造方法只執(zhí)行一次。init方法也只被Tomcat服務(wù)器調(diào)用一次。
-
第三:只要用戶發(fā)送一次請求:service方法必然會(huì)被Tomcat服務(wù)器調(diào)用一次。發(fā)送100次請求,service方法會(huì)被調(diào)用100次。
-
?????????關(guān)閉服務(wù)器的時(shí)候,控制臺(tái)輸出了以下內(nèi)容:
-
destroy方法是在什么時(shí)候被調(diào)用的?
-
在服務(wù)器關(guān)閉的時(shí)候。因?yàn)榉?wù)器關(guān)閉的時(shí)候要銷毀AServlet對象的內(nèi)存。服務(wù)器在銷毀AServlet對象內(nèi)存之前,Tomcat服務(wù)器會(huì)自動(dòng)調(diào)用AServlet對象的destroy方法。
-
ps:destroy方法調(diào)用的時(shí)候,對象還沒有銷毀(如果銷毀了那誰來調(diào)用destroy方法?),destroy方法執(zhí)行結(jié)束之后,AServlet對象的內(nèi)存才會(huì)被Tomcat釋放。