想要搞清楚這件事情,必須先了解Servlet容器調用Servlet的過程。調用過程如下
首次訪問該Servlet
1、調用init(ServletConfig config) 進行初始化, ServletConfig 封裝了web.xml中<init-param>配置的初始化參數,它由Servlet容器創建,並通過該方法傳遞給當前serlvet
2、調用service(ServletRequest req, ServletResponse res)方法處理客戶的請求
3、調用destroy()方法銷毀給Servlet實例,當然這里只是 為了說明完整流程,實際上destroy()方法不是在調用servlet完成后就銷毀。
1、調用init(ServletConfig config) 進行初始化, ServletConfig 封裝了web.xml中<init-param>配置的初始化參數,它由Servlet容器創建,並通過該方法傳遞給當前serlvet
2、調用service(ServletRequest req, ServletResponse res)方法處理客戶的請求
3、調用destroy()方法銷毀給Servlet實例,當然這里只是 為了說明完整流程,實際上destroy()方法不是在調用servlet完成后就銷毀。
后續訪問
該Servlet
1、調用service(ServletRequest req, ServletResponse res)方法處理客戶的請求
2、調用destroy()方法銷毀給Servlet實例,當然這里只是為了說明完整流程,實際上 destroy()方法不是在調用servlet完成后就銷毀。
1、調用service(ServletRequest req, ServletResponse res)方法處理客戶的請求
2、調用destroy()方法銷毀給Servlet實例,當然這里只是為了說明完整流程,實際上 destroy()方法不是在調用servlet完成后就銷毀。
從上面的調用過程來看,Serlvet容器僅關心帶參數的init方法init(ServletConfig config)、service(ServletRequest req, ServletResponse res)和destroy(),其他的額外方法都是附加產品,這樣也就說明不帶參數的init方法不是必須的,那為什么在GenericServlet抽象類中卻定義了該方法,意義何在呢?
我們先看下
GenericServlet類中的兩個init方法的實現。
public void init(ServletConfig config)throws ServletException{
this.config = config;
this.init();
}
public void init()throws ServletException{
}
public void init(ServletConfig config)throws ServletException{
this.config = config;
this.init();
}
public void init()throws ServletException{
}
從上面的實現來看,
init(ServletConfig config)會調用不帶參數的init方法進行初始化該Serlvet實例,而不帶參數的init方法卻什么都不做。
假設 GenericServlet類只實現了 init(ServletConfig config)方法,那么代碼應該如下
public void init(ServletConfig config)throws ServletException{
this.config = config;
}
假設 GenericServlet類只實現了 init(ServletConfig config)方法,那么代碼應該如下
public void init(ServletConfig config)throws ServletException{
this.config = config;
}
假設某個子類繼承了上面只定義一個init方法的
GenericServlet類,並且想再初始化時增加一些自己的初始化參數,那必須重寫
GenericServlet類的
init(ServletConfig config)方法,如下:
public class Test extends GenericServlet {
public int a = 0;
public String b;
public void init(ServletConfig config)throws ServletException{
super.init(config); //或者 this.config = config;
this.a = XXX;
this.b = XXX;
}
public void service ( ServletRequest req, ServletResponse res) throws ServletException , java.io.IOException{
....
}
}
public class Test extends GenericServlet {
public int a = 0;
public String b;
public void init(ServletConfig config)throws ServletException{
super.init(config); //或者 this.config = config;
this.a = XXX;
this.b = XXX;
}
public void service ( ServletRequest req, ServletResponse res) throws ServletException , java.io.IOException{
....
}
}
上面的這個實現類是沒問題的,我們可以正常使用
getServletConfig
()方法得到
ServletConfig對象進行使用。
但是假設開發過程中忘記了調用 super.init(config); //或者 this.config = config;這個語句,那么問題就大了, getServletConfig ()將返回null,無法使用 ServletConfig。所以 GenericServlet就再定義了一個無參的init( )方法,子類只需繼承該方法即可。這樣就防止了類似問題發生。
但是假設開發過程中忘記了調用 super.init(config); //或者 this.config = config;這個語句,那么問題就大了, getServletConfig ()將返回null,無法使用 ServletConfig。所以 GenericServlet就再定義了一個無參的init( )方法,子類只需繼承該方法即可。這樣就防止了類似問題發生。