Servlet 监听器
在Servlet API中有一个ServletContextListener接口,它能够监听ServletContext对象的生命周期,实际上就是监听Web应用的生命周期。
当Servlet容器启动或终止Web应用时,会触发ServletContextEvent事件,该事件由 ServletContextListener 来处理。在 ServletContextListener 接口中定义了处理 ServletContextEvent事件的两个方法。
contextInitialized(ServletContextEvent sce):当Servlet容器启动Web应用时调用该方法。在调用完该方法之后,容器再对Filter初始化,并且对那些在Web应用启动时就需要 被初始化的Servlet进行初始化
contextDestroyed(ServletContextEvent sce):当Servlet容器终止Web应用时调用该方法。在调用该方法之前,容器会先销毁所有的Servlet和Filter过滤器
1.spring监听器
ContextLoaderListener
public class org.springframework.web.context.ContextLoaderListener extends org.springframework.web.context.ContextLoader implements
javax.servlet.ServletContextListener {
}
2.servlet监听器
ServletContextListener
public abstract interface javax.servlet.ServletContextListener extends java.util.EventListener {
}
3.ContextLoader
public class org.springframework.web.context.ContextLoader {
}
web项目启动tomcat成功执行某个操作(比如缓存加载/日志记录/加载配置数据/)或者tomcat关掉后执行某个操作(比如资源释放/日志记录),都可以依靠监听器实现
No1.实现ServletContextListener接口,自定义一个监听器
public class MyListerner implements ServletContextListener{
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("tomcat注销");
}
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("tomcat初始化");
}
}
No2.在web.xml中配置此监听器
<listener>
<listener-class>demo.MyListerner</listener-class>
</listener>
No3.启动tomcat并关闭,控制台会输出
tomcat初始化
tomcat注销
上述代码功能同样可以使用servlet实现
No1.创建一个普通的Servlet类
public class ContextLoaderServlet extends HttpServlet{
public ContextLoaderServlet() {
super();
}
@Override
public void destroy() {
super.destroy();
System.out.println("Servlet销毁");
}
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
super.service(req, resp);
}
@Override
public void init() throws ServletException {
super.init();
System.out.println("Servlet初始化");
}
}
No2.在web.xml中配置servlet随容器加载而初始化
<servlet>
<servlet-name>ContextLoaderServlet</servlet-name>
<servlet-class>com.ttpod.common.view.servlet.ContextLoaderServlet</servlet-class>
<!-- 多个servlet值越小,加载优先级越大,销毁优先级越小 -->
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>ContextLoaderServlet</servlet-name>
<url-pattern>/servlet/ContextLoaderServlet</url-pattern>
</servlet-mapping>
No3.启动tomcat并关闭,控制台会输出
Servlet初始化
Servlet销毁
<load-on-startup>2</load-on-startup>节点配置使Servlet的生命周期和容器生命周期绑定到了一起,所以效果等同于
tomcat初始化
tomcat注销
如果同时配置了listener和servlet的监听器,listener优先级高于servlet,启动tomcat并关闭,控制台会输出
tomcat初始化
Servlet初始化
Servlet销毁
tomcat注销
虽然servlet可以充当监听器,但servlet的主要功能不是监听器,所以监听器的实现最好使用listener
使用listener可以通过ServletContextEvent获得ServletContext对象,对于容器的控制更方便灵活有效
备注:
No1.web.xml中监听器、过滤器、Servlet顺序问题
配置顺序:
ServletContext(ContextParam)-> filter -> listener -> servlet
加载顺序:
ServletContext(ContextParam) -> listener -> filter -> servlet
No2.web项目启动就加载servlet,需要配置<load-on-startup>2</load-on-startup>,如有多个servlet配置,其值越小,优先级越高,此时会初始化此servlet,也就是执行inite()方法
<load-on-startup>2</load-on-startup>节点不存在情况下,servlet被请求时才被初始化
No3.使用servlet作为监听器,好处在于可以在监听器里面使用spring mvc的功能
无论是配置还是注解实例化bean,都可以使用以下方式获得有状态的Bean实例:
//从xml中加载spring应用上下文(spring-servlet.xml含注解配置)
ApplicationContext ac = (ApplicationContext) new ClassPathXmlApplicationContext(new String[]{"/config/spring/applicationContext.xml","/config/spring/spring-servlet.xml"});
//从xml配置文件里获取SessionFactory对象
SessionFactory factory = (SessionFactory)ac.getBean("sessionFactory");
//从注解里获取IHeadService接口
IHeadService headService = (IHeadService)ac.getBean("headService");
AdvertController advertController = (AdvertController)ac.getBean("advertController");