一、Servlet的继承关系
假如现有咱们自定义的一个Servlet,继承HttpServlet,那么实际上它的继承链以下图:
能够看到,核心的部分在于:
- 两个顶级接口
- 接口的实现类
- 基于HTTP协议的实现类
咱们剥离一下,把不须要看的去掉,再把方法显示一下,可清晰知道
Servlet的总体继承关系以下:
其中重点摘录部分进行说明:
- ServletConfig Servlet的配置信息,经常使用来在Servlet初始化时进行信息传递
- getServletContext() 获取Servlet运行的上下文环境对象,能够获取对应信息(如Servlet路径),存取容量级的变量
- getInitParameter(String name) 获取初始化参数(web.xml中配置的init-param)
- GenericServlet 通常的Servlet,实现了Servlet和ServletConfig接口
- init(ServletConfig config) 初始化方法,方法中调用了init()
- init() 初始化方法,方法体为空,主要用于自定义Servlet的覆盖
- service(ServletRequest request, ServletResponse response) 抽象方法service,要求继承类实现
- destory() Servlet销毁前要执行的方法
- HttpServlet 基于HTTP协议的实现类
- service(ServletRequest request, ServletResponse response) 实现了GenericServlet的抽象方法,调用了service(HttpServletRequest, HttpServletResponse)
- service(HttpServletRequest request, HttpServletResponse response) 根据请求的不一样调用了doGet或doPost方法
- doGet() 处理GET方式的请求
- doPost() 处理POST方式的请求
其中稍微提一下,在GenericServlet中有个init(ServletConfig config)方法,调用了init()方法,可是init()方法体却为空,为何?
public void init(ServletConfig config) throws ServletException {
this.config = config;
this.init();
}
public void init() throws ServletException {
}
首先,为了方便可以在其余地方也能直接使用ServletConfig对象,而不单单局限在init(ServletConfig config)方法中,因此建立一个私有的成员变量config,在init(ServletConfig config)方法中就将其赋值给config,这样一来,GenericServlet和其子类均可以调用其getServletConfig()方法来获取ServletConfig对象了。
之因此有空的init(),实际上就是为了后续的扩展和重写,有须要的状况下去覆盖init()而不是去覆盖init(ServletConfig config),由于后者一旦覆盖,就没法经过上述的方法在其余地方便捷地调用getServletConfig方法获取ServletConfig对象了。
实际上,Servlet继承关系文字描述起来反而复杂,结合继承图和源码查看,能更加清晰明了,这里进行了大概的阐述,更多细节的话须要查看源码或者API了,此处再也不详细展开。
二、Servlet的生命周期
Servlet之间的启动是有前后顺序的,这能够在web.xml中经过<load-on-startup>标签进行设定,参数为数字,表示了启动的顺序。启动顺序的默认值是0:
- load-on-startup --> 0:Servlet被访问时才进行实例化
- load-on-startup --> other:在容器启动时进行Servlet实例化
便是说,
默认不配置该参数的状况下,Servlet只有再被访问时才会实例化;配置了参数之后,根据参数按顺序在容器启动时就将Servlet实例化。
而后,Servlet的生命周期,其实说来也简单:
- 容器在加载Servlet的时候,会执行其init()方法
- 当接收请求的时候,会调用service(ServletReqeust request, ServletResponse response)方法,继而调用doGet或doPost方法
- 在服务器关闭以前,会调用Servlet的destory()方法
即:
- init()
- doGet() / doPost()
- destory()
实际上,完整一点来讲:
- 初始化
- 构造方法
- init(ServletConfig config)
- init()
- 提供服务
- service(ServletRequest request, ServletResponse response)
- doGet() / doPost()
- 销毁
(写得有点啰嗦...)
最后简单总结下要点:
- Servlet只初始化一次,它是单例的,只有一个实例,经过多线程访问。即Servlet是多线程单实例的
- 实例化过程当中,先调用构造方法,再调用init方法,因此初始化操做能够覆盖写到init方法中
- 请求方式不一样会调用doGet()或doPost()方法
- 根据实际状况在Servlet销毁前调用其destroy()方法