🔥 Let’s explore how a servlet container manages the servlet lifecycle step by step — including when and what methods are called.
🌀 Servlet Life Cycle Overview
The servlet container (like Tomcat or Jetty) controls the life of a servlet. It goes through three main phases:
1. Loading & Instantiation
2. Initialization (init)
3. Request Handling (service → doGet/doPost)
4. Destruction (destroy)
📦 1. Loading & Instantiation
- When: The first time the servlet is requested, or at startup if
load-on-startup
is set inweb.xml
. - What: The container loads the servlet class and creates a single instance.
public class MyServlet extends HttpServlet {
// Constructor is optional
public MyServlet() {
super();
System.out.println("Constructor: Servlet instance created");
}
}
Servlet container ensures only one instance per servlet — it’s multithreaded!
⚙️ 2. Initialization – init()
- When: Called once after instantiation
- What: Initializes the servlet — great place to read config params, set up DB connections, etc.
@Override
public void init(ServletConfig config) throws ServletException {
super.init(config);
System.out.println("init(): Called once after servlet instantiation");
}
Only called once per servlet lifecycle.
🔁 3. Request Handling – service()
- When: Every time a request is made to the servlet (e.g., from browser or REST client)
- What: The container spawns a new thread and calls the
service()
method.
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.getWriter().write("Hello from doGet!");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
res.getWriter().write("Hello from doPost!");
}
The service()
method routes to doGet()
, doPost()
, doPut()
, etc., based on the HTTP method.
❌ 4. Destruction – destroy()
- When: When the server is shutting down or the servlet is being undeployed.
- What: Cleans up resources (e.g., closing DB connections, stopping threads).
@Override
public void destroy() {
System.out.println("destroy(): Called once before servlet is removed");
}
Only called once — time to release heavy resources.
🚀 Summary Flowchart
+------------------+
| Class Loaded |
+------------------+
↓
+------------------+
| new MyServlet() |
+------------------+
↓
+------------------+
| init() |
+------------------+
↓
+-------------------------------+
| service() → doGet()/doPost() |
+-------------------------------+
↓ (many times!)
+------------------+
| destroy() |
+------------------+
🧠 Pro Tips
- Thread-safety: Because multiple requests are handled by threads on a single servlet instance, make sure shared data is synchronized.
- init() vs constructor: Prefer
init()
for any config logic — container has more control here. - destroy() cleanup: Essential for avoiding memory leaks.