1 监听器概念
监听器 Listener 就是一个实现特定接口的 Java 程序,它是随 web 应用的启动而启动,只初始化一次,随 web 应用的停止而销毁。监听器的主要作用是:做一些初始化的内容添加工作或者设置一些基本的内容等等,例如监听器就可以用于统计在线人数或者自定义 session 扫描器等等。
2 监听器分类
根据监听的对象不同,可以划分为以下三种:
- 用于监听应用程序环境对象(ServletContext)的事件监听器;
- 用于监听用户会话对象(HttpSession)的事件监听器;
- 用于监听请求消息对象(ServletRequest)的事件监听器。
在一个 web 应用程序的整个运行周期内,web 容器会创建和销毁三个重要的对象,分别为:ServletContext、HttpSession 和 ServletRequest. 在 servlet 2.4 中定义了三个接口,分别为:ServletContextListener、HttpSessionListener 和 ServletRequestListener。
- ServletContextListener:用于监听 web 应用启动和销毁的事件,监听器类需要实现ServletContextListener接口;
- ServletContextAttributeListener:用于监听 web 应用属性改变的事件,包括增加属性、删除属性、修改属性等,监听器类需要实现ServletContextAttributeListener接口;
- HttpSessionListener:用于监听 session 对象的创建和销毁,监听器类需要实现HttpSessionListener接口或者HttpSessionActivationListener接口,或者两个都实现。
咱们通过分别实现对应的接口就可以实现对应的监听处理,例如在 ServletContextListener 接口中定义了两个事件处理方法,分别是contextInitialized()和contextDestroyed():
- public void contextInitialized(ServletcontextEvent paramServletContextEvent),该方法接受一个 ServletContextEvent 类型的参数,因此该方法可以通过这个参数获得当前被创建的 ServletContext 对象;
- public void contextDestroyed(ServletContextEvent paramServletContextEvent),该方法用于销毁对象。
如果咱们实现了以上两个方法,咱们也就实现了监听 web 应用启动和销毁的功能。在这里,咱们不妨顺便看看 ServletContextListener 接口的源代码:
public abstract interface ServletContextListener extends EventListener{
public abstract void contextInitialized(ServletContextEvent paramServletContextEvent);
public abstract void contextDestroyed(ServletContextEvent paramServletContextEvent);
}
3 监听器应用示例
3.1 示例 1:初始化数据库连接池
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.apache.commons.dbcp.BasicDataSource;
/**
* 示例代码:使用监听器对数据库连接池 DataSource 进行初始化
*/
public class ListenerTest implements ServletContextListener{
// 应用监听器的销毁方法
public void contextDestroyed(ServletContextEvent servletContextEvent) {
ServletContext servletContext = servletContextEvent.getServletContext();
// 在整个web应用销毁之前调用,将所有应用空间所设置的内容清空
servletContext.removeAttribute("dataSource");
System.out.println("销毁工作完成...");
}
// 应用监听器的初始化方法
public void contextInitialized(ServletContextEvent servletContextEvent) {
// 通过这个事件可以获取整个应用的空间
// 在整个web应用下面启动的时候做一些初始化的内容添加工作
ServletContext servletContext = servletContextEvent.getServletContext();
// 设置一些基本的内容;比如一些参数或者是一些固定的对象
// 创建 DataSource 对象,连接池技术 dbcp
BasicDataSource basicDataSource = new BasicDataSource();
basicDataSource.setDriverClassName("com.jdbc.Driver");
basicDataSource.setUrl("jdbc:mysqlocalhost:3306/");
basicDataSource.setUsername("root");
basicDataSource.setPassword("root");
basicDataSource.setMaxActive(10); //最大连接数
basicDataSource.setMaxIdle(5); //最大管理数
// basicDataSource.setMaxWait(maxWait); 最大等待时间
// 把 DataSource 放入 ServletContext 空间中,
// 供整个web应用的使用(获取数据库连接)
servletContext.setAttribute("dataSource", basicDataSource);
System.out.println("应用监听器初始化工作完成...");
System.out.println("已经创建 DataSource...");
}
}
在 web.xml 文件中配置监听器:
<!-- 配置监听器 -->
<listener>
<!-- 监听器的包路径 -->
<listener-class>com.hit.listener.ListenerTest</listener-class>
</listener>
3.2 示例 2:统计当前在线人数
import javax.servlet.ServletContext;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* 利用 HttpSessionListener 监听器实现统计网站在线人数的功能
*/
public class SessionListener implements HttpSessionListener{
public static int TOTAL_ONLINE_USERS = 0;
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
TOTAL_ONLINE_USERS = (Integer) servletContext.getAttribute("TOTAL_ONLINE_USERS");
// 如果用户退出,TOTAL_ONLINE_USERS 自减 1
if(TOTAL_ONLINE_USERS == 0){
servletContext.setAttribute("TOTAL_ONLINE_USERS", 1);
}
else{
TOTAL_ONLINE_USERS--;
servletContext.setAttribute("TOTAL_ONLINE_USERS", TOTAL_ONLINE_USERS);
}
}
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
ServletContext servletContext = httpSessionEvent.getSession().getServletContext();
TOTAL_ONLINE_USERS = (Integer) servletContext.getAttribute("TOTAL_ONLINE_USERS");
// 如果用户登录,TOTAL_ONLINE_USERS 自增 1
if(TOTAL_ONLINE_USERS == 0){
servletContext.setAttribute("TOTAL_ONLINE_USERS", 1);
}
else{
TOTAL_ONLINE_USERS++;
servletContext.setAttribute("TOTAL_ONLINE_USERS", TOTAL_ONLINE_USERS);
}
}
}
在 web.xml 文件中配置监听器:
<!-- 配置监听器 -->
<listener>
<!-- 监听器的包路径 -->
<listener-class>com.hit.listener.SessionListener</listener-class>
</listener>
参考文献:
1.Java监听器
2.Java过滤器和监听器详解、
3.Java三大器之监听器(Listener)的工作原理和代码演示