servlet的每个实例与servlet中的servlet的每个线程之间的区别?
问题内容:
servlet类有多个实例吗?当我听到“每个servlet实例”时,有人可以详细说明吗?
问题答案:
Servlet容器启动时,它:
- 读
web.xml
; - 在类路径中找到已声明的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()
。
您会看到,servlet容器为每个请求重用了相同的servlet实例。换句话说:servlet在每个request之间共享。这就是为什么它是要编写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.
}
}