servlet类有多个实例吗?当我听到“每个servlet实例”时,有人可以详细说明吗?
Servlet容器启动时,它:
web.xml
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()。
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. } }