是否有多個servlet類的實例?當我聽到「servlet的每個實例」 有沒有人可以詳細說明這一點?servlet的每個實例與servlet中每個servlet的線程之間的區別?
回答
當Servlet容器啓動時,它:
- 讀取
web.xml
; - 在classpath中查找已聲明的Servlet;和
- 加載和實例化每個Servlet 只有一次。
粗略地說,像這樣的:
String urlPattern = parseWebXmlAndRetrieveServletUrlPattern();
String servletClass = parseWebXmlAndRetrieveServletClass();
HttpServlet servlet = (HttpServlet) Class.forName(servletClass).newInstance();
servlet.init();
servlets.put(urlPattern, servlet); // Similar to a map interface.
這些Servlet的存儲在內存中,並重復使用,每次請求的URL匹配的Servlet的相關url-pattern
。 servlet容器然後執行類似操作的代碼:
for (Entry<String, HttpServlet> entry : servlets.entrySet()) {
String urlPattern = entry.getKey();
HttpServlet servlet = entry.getValue();
if (request.getRequestURL().matches(urlPattern)) {
servlet.service(request, response);
break;
}
}
的GenericServlet#service()
它反過來決定哪個的doGet()
,doPost()
等。調用基於HttpServletRequest#getMethod()
。
您會發現,servletcontainer對每個請求重用相同的servlet實例。換句話說:servlet在之間共享,每個請求。這就是爲什麼以線程安全方式編寫servlet代碼非常重要 - 實際上很簡單:只需執行而不是將請求或會話作用域數據分配爲servlet實例變量,但僅作爲方法局部變量。例如。
public class MyServlet extends HttpServlet {
private Object thisIsNOTThreadSafe;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
Object thisIsThreadSafe;
thisIsNOTThreadSafe = request.getParameter("foo"); // BAD!! Shared among all requests!
thisIsThreadSafe = request.getParameter("foo"); // OK, this is thread safe.
}
}
+1。我將補充一點,如果在web.xml中將相同的servlet類映射到兩個不同的URL,那麼會創建兩個實例。但總體原則仍然成立,一個例子服務於多個要求。 – Yoni 2010-02-02 13:55:51
@BalusC,奇怪的是,有沒有一種方法可以從Web應用程序訪問一組已啓動的Servlet? – shabunc 2012-03-21 19:03:55
該類中的變量thisIsNOTThreadSafe是否被共享給不同的用戶,或者只被共享給同一用戶的不同頁面。我的意思是,如果我在計算機中瀏覽此頁面,並在計算機上運行,我們是否共享這個非線程安全的相同空間?謝謝。 – overshadow 2014-08-25 10:01:08
不,只有一個servlet實例可用於來自多個客戶端的多個請求。這導致了兩條重要規則:
- 不使用servlet中的實例變量,除了應用程序範圍的值(通常從上下文參數獲得)之外。
- 不作方法在servlet
(同樣適用於Servlet過濾器和JSP)
不能有Servlet類的多個實例。即使有一個servlet實例,它也能夠處理多個請求。所以不使用類級變量是明智的。
根據Java Servlet規範版本3.0(第6-7頁),將有每JVM聲明一個實例,除非該servlet實現了SingleThreadModel在這種情況下可能存在每個JVM多個實例。
Servlet規範3.(第6-7頁)第2.2.1節有關單線程模型的注意事項,說「SingleThreadModel接口在此版本的規範中已被棄用「。 – Reva 2015-12-22 22:35:05
對於那些知道真正的JavaScript(不只是它的庫)的人來說,Servlets可以被看作是函數對象。作爲功能對象,他們的主要任務是做,而不是存儲一些信息在他們的胸前。沒有必要實例化每個這樣的功能對象的多個實例,其原理與Java類方法在該類的所有實例中共享的原理相同。
儘管已經有幾個很好的答案,但他們都沒有提到部署在分佈式環境中的Java Web應用程序。這是一個實際的場景,實際上創建了單個servlet的多個實例。在分佈式環境中,您有一組機器來處理請求,並且請求可以轉到任何這些機器。這些機器中的每一個都應該能夠處理請求,因此每臺機器都應該在其JVM中擁有一個MyAwesomeServlet實例。
因此,正確的語句是每個JVM只有一個實例,除非它實現了SingleThreadModel。
SimpleThreadModel用簡單的話說,每個Servlet實例只需要一個線程,所以基本上你需要爲每個來到的請求創建一個實例來處理它,它基本上殺死了以並行方式處理請求的整個概念並且不被認爲是一種好的做法,因爲在準備好處理請求之前,servlet對象的創建和初始化需要時間。
- 1. dispatcher-servlet和spring-servlet之間的區別
- 2. javax.servlet-api.jar與servlet-api.jar之間的區別
- 3. Servlet中getLocalPort()和getServerPort()之間的區別
- 4. 識別Servlet中的每個請求線程
- 5. <servlet-path>和<servlet-class>標籤之間的區別?
- 6. java,java EE,servlet,JDK之間的區別
- 7. PHP和Servlet之間的主要區別
- 8. FastCGI和Java Servlet API之間的區別
- 9. 爲每個訪問者啓動一個線程的Servlet
- 10. 每個路徑一個Servlet或處理Servlet中的多個路徑?
- 11. 訪問一個servlet實例
- 12. Servlet線程池vs Servlet實例池 - 通過web容器
- 13. 每個webapp有一個或多個servlet?
- 14. servlet/servlet映射和過濾器/過濾器映射之間的區別?
- 15. 線程在servlet的
- 16. Servlet和JSP的區別?
- 17. 的servlet:在Servlet中
- 18. 跨多個映射的Servlet實例
- 19. 多個實例時的Servlet同步
- 20. JBoss 4.2.3如何實現SingleThreadModel(STM):一個servlet的實例或一個servlet的多個實例?
- 21. Servlet線程池
- 22. servlet多線程
- 23. 的Java Servlet:發送重定向和轉發servlet的區別
- 24. 線程安全與servlet中的CopyOnArrayList
- 25. 非Java EE 5 servlet和Java EE 5 servlet容器之間有什麼區別?
- 26. servlet擴展另一個servlet
- 27. 這個servlet是線程安全的嗎?
- 28. Applet和Servlet之間的區別以及它們的用法
- 29. 網絡服務和基於文本的servlet之間的區別
- 30. 的Oauth + Java servlet爲+ OAuthSigner + Servlet類實例化的錯誤
不!只有通過調用newInstance()方法,Web容器纔會在第一次請求時僅創建一個servlet實例。 – 2012-05-10 18:52:26