Hi I am confused .. Are there multiple instances of servlet class? As I hear "each instance of servlet" Can anybody elaborate on this?
views:
527answers:
4No, there is only one instance of the servlet which is reused for multiple requests from multiple clients. This leads to two important rules:
- don't use instance variables in a servlet, except for application-wide values, most often obtained from context parameters.
- don't make methods
synchronized
in a servlet
(same goes for servlet filters and jsps)
There can be multiple instances of servlet class. Even when there is one instance of the servlet, it is able to handle multiple requests. So it is wise not to use class level variables.
There is single instance of servlet in a servlet container. This single instance is responsible for servicing all requests. You can read about servlet life cycle here.
Of course if you have more than one containers (in a cluster environment for example), you have multiple instances.
When the servletcontainer starts up, it reads the web.xml
, lookups the declared servlets in the classpath, loads and instantiates them only once. It roughly look like this:
String urlPattern = parseWebXmlAndRetrieveServletUrlPattern();
String servletClass = parseWebXmlAndRetrieveServletClass();
HttpServlet servlet = (HttpServlet) Class.forName(servletClass).newInstance();
servlet.init();
servlets.put(urlPattern, servlet); // It's roughly said a Map.
Those servlets are stored in server's memory and reused everytime when the request URL matches the with the servlet associated url-pattern
. The servletcontainer roughly do like this for every request:
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;
}
}
The GenericServlet#service()
on its turn decides which of the doGet()
, doPost()
, etc.. to invoke based on HttpServletRequest#getMethod()
.
You see, the servletcontainer reuses the same servlet instance for every request. In other words: the servlets are shared among every request. That's why it's extremely important to write servlet code the threadsafe manner --which is actually simple: just do not assign request or session scoped data as servlet instance variables, but just as method local variables. E.g.
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.
}
}