Servlet----ServletContext
在正式講解之前,先讓大家有一個(gè)整體印象。
之前講過(guò)ServletConfig,我發(fā)現(xiàn)他們有兩個(gè)共同的方法,我對(duì)他們的區(qū)別做了小小的總結(jié)
JavaWeb系列的其他教程,持續(xù)更新中
JavaWeb系列教程
JavaWeb—Servlet
模擬Servlet本質(zhì)
使用IDEA開發(fā)Servlet程序
Servlet對(duì)象的生命周期
適配器(GenericServlet)改造Servlet
ServletConfig
Servlet–ServletContext
HTTP協(xié)議,get和post的區(qū)別
web站點(diǎn)歡迎頁(yè)
一篇學(xué)會(huì)HttpServletRequest
上面的思維導(dǎo)圖是對(duì)下面內(nèi)容的總結(jié),大家可以先看看,對(duì)等會(huì)的內(nèi)容有一個(gè)大概印象,看完后,可以再回頭看看這個(gè)思維導(dǎo)圖。
如果大家覺(jué)得有幫助的話,不妨動(dòng)動(dòng)小手,點(diǎn)贊收藏一波,也方便后面的復(fù)習(xí)哈
ServletContext是什么
-
ServletContext是一個(gè)接口,是Servlet規(guī)范中的一員,
-
ServletContext對(duì)象的創(chuàng)建也是Tomcat服務(wù)器來(lái)完成的。啟動(dòng)webapp的時(shí)候創(chuàng)建的。
-
ServletContext是誰(shuí)實(shí)現(xiàn)的
Tomcat服務(wù)器(WEB服務(wù)器)實(shí)現(xiàn)了ServletContext接口
public class org.apache.catalina.core.ApplicationContextFacade implements ServletContext{} -
Servlet對(duì)象是誰(shuí)創(chuàng)建的,在什么時(shí)候創(chuàng)建的
ServletContext對(duì)象是WEB服務(wù)器啟動(dòng)的時(shí)候創(chuàng)建的
ServletContext對(duì)象是WEB服務(wù)器創(chuàng)建的
ServletContext的生命周期
-
對(duì)于一個(gè)WEBAPP來(lái)說(shuō),ServletContext對(duì)象只有一個(gè)
-
一個(gè)web應(yīng)用對(duì)應(yīng)一個(gè)ServletContext實(shí)例,這個(gè)實(shí)例是應(yīng)用部署啟動(dòng)后,servlet容器為應(yīng)用創(chuàng)建的。
-
ServletContext對(duì)象在服務(wù)器關(guān)閉的時(shí)候銷毀
- 一個(gè)Servlet對(duì)象對(duì)應(yīng)一個(gè)ServletConfig。100個(gè)Servlet對(duì)象則對(duì)應(yīng)100個(gè)ServletConfig對(duì)象。
-
只要在同一個(gè)webapp當(dāng)中,只要在同一個(gè)應(yīng)用當(dāng)中,所有的Servlet對(duì)象都是共享同一個(gè)ServletContext對(duì)象的。
-
ServletContext對(duì)象在服務(wù)器啟動(dòng)階段創(chuàng)建,在服務(wù)器關(guān)閉的時(shí)候銷毀。這就是ServletContext對(duì)象的生命周期。ServletContext對(duì)象是應(yīng)用級(jí)對(duì)象。
-
Tomcat服務(wù)器中有一個(gè)webapps,這個(gè)webapps下可以存放webapp,可以存放多個(gè)webapp,假設(shè)有100個(gè)webapp,那么就有100個(gè)ServletContext對(duì)象。但是,總之,一個(gè)應(yīng)用,一個(gè)webapp肯定是只有一個(gè)ServletContext對(duì)象。
接下來(lái),通過(guò)程序驗(yàn)證一下
ServletContext servletContext = this.getServletContext();response.setContentType("text/html");PrintWriter writer = response.getWriter();writer.print("ServletContext對(duì)象:"+servletContext+"<br>");
一個(gè)webapp應(yīng)用共享一個(gè)ServletContext對(duì)象
ServletContext servletContext = this.getServletContext();response.setContentType("text/html");PrintWriter writer = response.getWriter();writer.print("ServletContext對(duì)象:"+servletContext+"<br>");
-
ServletContext被稱為Servlet上下文對(duì)象。(Servlet對(duì)象的四周環(huán)境對(duì)象。)
-
一個(gè)ServletContext對(duì)象通常對(duì)應(yīng)的是一個(gè)web.xml文件。
-
ServletContext對(duì)應(yīng)顯示生活中的什么例子呢?
-
一個(gè)教室里有多個(gè)學(xué)生,那么每一個(gè)學(xué)生就是一個(gè)Servlet,這些學(xué)生都在同一個(gè)教室當(dāng)中,那么我們可以把這個(gè)教室叫做ServletContext對(duì)象。那么也就是說(shuō)放在這個(gè)ServletContext對(duì)象(環(huán)境)當(dāng)中的數(shù)據(jù),在同一個(gè)教室當(dāng)中,物品都是共享的。比如:教室中有一個(gè)空調(diào),所有的學(xué)生都可以操作。可見(jiàn),空調(diào)是共享的。因?yàn)榭照{(diào)放在教室當(dāng)中。教室就是ServletContext對(duì)象。
-
Tomcat是一個(gè)容器,一個(gè)容器可以放多個(gè)webapp,一個(gè)webapp對(duì)應(yīng)一個(gè)ServletContext對(duì)象
-
ServletContext接口中常用的方法
-
public String getInitParameter(String name); // 通過(guò)初始化參數(shù)的name獲取value
public Enumeration<String> getInitParameterNames(); // 獲取所有的初始化參數(shù)的name
ServletContext servletContext = this.getServletContext();response.setContentType("text/html");PrintWriter writer = response.getWriter();writer.print("ServletContext對(duì)象:"+servletContext+"<br>");String initParameter = servletContext.getInitParameter("pageSize");writer.println("pageSize= "+initParameter);
Enumeration<String> names = servletContext.getInitParameterNames();while (names.hasMoreElements()){String s = names.nextElement();//通過(guò)name獲取valueString initParameter = servletContext.getInitParameter(s);writer.println(s+"--->"+initParameter+"<br>");}
<!--以上兩個(gè)方法是ServletContext對(duì)象的方法,這個(gè)方法獲取的是什么信息?是以下的配置信息-->
<context-param><param-name>pageSize</param-name><param-value>10</param-value>
</context-param>
<context-param><param-name>startIndex</param-name><param-value>0</param-value>
</context-param>
<!--注意:以上的配置信息屬于應(yīng)用級(jí)的配置信息,一般一個(gè)項(xiàng)目中共享的配置信息會(huì)放到以上的標(biāo)簽當(dāng)中。-->
<!--如果你的配置信息只是想給某一個(gè)servlet作為參考,那么你配置到servlet標(biāo)簽當(dāng)中即可,使用ServletConfig對(duì)象來(lái)獲取。-->
獲取應(yīng)用的根路徑(非常重要),因?yàn)樵趈ava源代碼當(dāng)中有一些地方可能會(huì)需要應(yīng)用的根路徑,這個(gè)方法可以動(dòng)態(tài)獲取應(yīng)用的根路徑
在java源碼當(dāng)中,不要將應(yīng)用的根路徑寫死,因?yàn)槟阌肋h(yuǎn)都不知道這個(gè)應(yīng)用在最終部署的時(shí)候,起一個(gè)什么名字。
獲取項(xiàng)目的根路徑獲取應(yīng)用的根路徑(非常重要),因?yàn)樵趈ava源代碼當(dāng)中有一些地方可能會(huì)需要應(yīng)用的根路徑,這個(gè)方法可以動(dòng)態(tài)獲取應(yīng)用的根路徑在java源碼當(dāng)中,不要將應(yīng)用的根路徑寫死,因?yàn)槟阌肋h(yuǎn)都不知道這個(gè)應(yīng)用在最終部署的時(shí)候,起一個(gè)什么名字。writer.print("獲取項(xiàng)目的根路徑:");String contextPath = servletContext.getContextPath();// /servlet04writer.println(contextPath+"<br>");
獲取文件的絕對(duì)路徑String realPath = servletContext.getRealPath("AServlet.java");writer.println(realPath+"<br>");
通過(guò)ServletContext對(duì)象也是可以記錄日志的
public void log(String message);
public void log(String message, Throwable t);這些日志信息記錄到哪里了?localhost.2022-03-12.logTomcat服務(wù)器的logs目錄下都有哪些日志文件?catalina.2022-03-12.log 服務(wù)器端的java程序運(yùn)行的控制臺(tái)信息。localhost.2022-03-12.log ServletContext對(duì)象的log方法記錄的日志信息存儲(chǔ)到這個(gè)文件中。localhost_access_log.2022-03-12.txt 訪問(wèn)日志
應(yīng)用域(重點(diǎn))
ServletContext對(duì)象還有另一個(gè)名字:應(yīng)用域(后面還有其他域,例如:請(qǐng)求域、會(huì)話域)
如果所有的用戶共享一份數(shù)據(jù),并且這個(gè)數(shù)據(jù)很少的被修改,并且這個(gè)數(shù)據(jù)量很少,可以將這些數(shù)據(jù)放到ServletContext這個(gè)應(yīng)用域中
為什么是所有用戶共享的數(shù)據(jù)? 不是共享的沒(méi)有意義。因?yàn)镾ervletContext這個(gè)對(duì)象只有一個(gè)。只有共享的數(shù)據(jù)放進(jìn)去才有意義。
為什么數(shù)據(jù)量要小? 因?yàn)閿?shù)據(jù)量比較大的話,太占用堆內(nèi)存,并且這個(gè)對(duì)象的生命周期比較長(zhǎng),服務(wù)器關(guān)閉的時(shí)候,這個(gè)對(duì)象才會(huì)被銷毀。大數(shù)據(jù)量會(huì)影響服務(wù)器的性能。占用內(nèi)存較小的數(shù)據(jù)量可以考慮放進(jìn)去。
為什么這些共享數(shù)據(jù)很少的修改,或者說(shuō)幾乎不修改?
所有用戶共享的數(shù)據(jù),如果涉及到修改操作,必然會(huì)存在線程并發(fā)所帶來(lái)的安全問(wèn)題。所以放在ServletContext對(duì)象中的數(shù)據(jù)一般都是只讀的。
數(shù)據(jù)量小、所有用戶共享、又不修改,這樣的數(shù)據(jù)放到ServletContext這個(gè)應(yīng)用域當(dāng)中,會(huì)大大提升效率。因?yàn)閼?yīng)用域相當(dāng)于一個(gè)緩存,放到緩存中的數(shù)據(jù),下次在用的時(shí)候,不需要從數(shù)據(jù)庫(kù)中再次獲取,大大提升執(zhí)行效率。
存(怎么向ServletContext應(yīng)用域中存數(shù)據(jù))
public void setAttribute(String name, Object value); map.put(k, v)取(怎么從ServletContext應(yīng)用域中取數(shù)據(jù))
public Object getAttribute(String name); Object v = map.get(k)刪(怎么刪除ServletContext應(yīng)用域中的數(shù)據(jù))
public void removeAttribute(String name); map.remove(k)
- 注意:以后我們編寫Servlet類的時(shí)候,實(shí)際上是不會(huì)去直接繼承GenericServlet類的,因?yàn)槲覀兪荁/S結(jié)構(gòu)的系統(tǒng),這種系統(tǒng)是基于HTTP超文本傳輸協(xié)議的,在Servlet規(guī)范當(dāng)中,提供了一個(gè)類叫做HttpServlet,它是專門為HTTP協(xié)議準(zhǔn)備的一個(gè)Servlet類。我們編寫的Servlet類要繼承HttpServlet。(HttpServlet是HTTP協(xié)議專用的。)使用HttpServlet處理HTTP協(xié)議更便捷。但是你需要知道它的繼承結(jié)構(gòu):
> jakarta.servlet.Servlet(接口)【爺爺】
> jakarta.servlet.GenericServlet implements Servlet(抽象類)【兒子】
> jakarta.servlet.http.HttpServlet extends GenericServlet(抽象類)【孫子】
>
> 我們以后編寫的Servlet要繼承HttpServlet類。
大家到目前為止都接觸過(guò)哪些緩存機(jī)制了?
- 堆內(nèi)存當(dāng)中的字符串常量池。
- “abc” 先在字符串常量池中查找,如果有,直接拿來(lái)用。如果沒(méi)有則新建,然后再放入字符串常量池。
- 堆內(nèi)存當(dāng)中的整數(shù)型常量池。
- [-128 ~ 127] 一共256個(gè)Integer類型的引用,放在整數(shù)型常量池中。沒(méi)有超出這個(gè)范圍的話,直接從常量池中取。
- 連接池(Connection Cache)
- 這里所說(shuō)的連接池中的連接是java語(yǔ)言連接數(shù)據(jù)庫(kù)的連接對(duì)象:java.sql.Connection對(duì)象。
- JVM是一個(gè)進(jìn)程。MySQL數(shù)據(jù)庫(kù)是一個(gè)進(jìn)程。進(jìn)程和進(jìn)程之間建立連接,打開通道是很費(fèi)勁的。是很耗費(fèi)資源的。怎么辦?可以提前先創(chuàng)建好N個(gè)Connection連接對(duì)象,將連接對(duì)象放到一個(gè)集合當(dāng)中,我們把這個(gè)放有Connection對(duì)象的集合稱為連接池。每一次用戶連接的時(shí)候不需要再新建連接對(duì)象,省去了新建的環(huán)節(jié),直接從連接池中獲取連接對(duì)象,大大提升訪問(wèn)效率。
- 連接池
- 最小連接數(shù)
- 最大連接數(shù)
- 連接池可以提高用戶的訪問(wèn)效率。當(dāng)然也可以保證數(shù)據(jù)庫(kù)的安全性。
- 線程池
- Tomcat服務(wù)器本身就是支持多線程的。
- Tomcat服務(wù)器是在用戶發(fā)送一次請(qǐng)求,就新建一個(gè)Thread線程對(duì)象嗎?
- 當(dāng)然不是,實(shí)際上是在Tomcat服務(wù)器啟動(dòng)的時(shí)候,會(huì)先創(chuàng)建好N多個(gè)線程Thread對(duì)象,然后將線程對(duì)象放到集合當(dāng)中,稱為線程池。用戶發(fā)送請(qǐng)求過(guò)來(lái)之后,需要有一個(gè)對(duì)應(yīng)的線程來(lái)處理這個(gè)請(qǐng)求,這個(gè)時(shí)候線程對(duì)象就會(huì)直接從線程池中拿,效率比較高。
- 所有的WEB服務(wù)器,或者應(yīng)用服務(wù)器,都是支持多線程的,都有線程池機(jī)制。
- redis
- NoSQL數(shù)據(jù)庫(kù)。非關(guān)系型數(shù)據(jù)庫(kù)。緩存數(shù)據(jù)庫(kù)。
- 向ServletContext應(yīng)用域中存儲(chǔ)數(shù)據(jù),也等于是將數(shù)據(jù)存放到緩存cache當(dāng)中了。
本次內(nèi)容到這里就結(jié)束了,感謝大家的支持,javaweb系列的教程正在持續(xù)更新
希望得到大家的支持
總結(jié)
以上是生活随笔為你收集整理的Servlet----ServletContext的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 适配器(GenericServlet)改
- 下一篇: 一篇学会HttpServletReque