一文吃透 Servlet 监听器:概念、常用接口与实战使用

前言

在 Java Web 开发体系中,Servlet 三大核心组件分别是:Servlet、Filter、Listener。很多同学熟练掌握了 Servlet 业务开发与过滤器拦截操作,却常常忽略Servlet 监听器的作用。

监听器作为 Web 容器的事件回调机制,能够监听 Web 项目中三大域对象的生命周期、属性变化等事件,无需手动调用,由容器自动触发执行。本文带你从零理解 Servlet 监听器,梳理核心接口、分类场景,搭配完整代码示例,快速掌握实际开发用法。

一、Servlet 监听器简介

1. 核心定义

Servlet 监听器是 Java Web 提供的一组特殊接口,用于监听 Web 容器中的事件。容器在触发指定行为时(项目启动 / 销毁、会话创建 / 失效、请求创建 / 结束、域对象属性增删改),会自动调用监听器中对应的回调方法,实现事件的统一处理。

2. 核心特点

  1. 被动触发:不需要手动创建对象、调用方法,Tomcat 等 Web 容器自动管理、自动执行;
  2. 解耦开发:将项目初始化、资源释放、在线人数统计、日志记录等通用逻辑抽离,和业务代码解耦;
  3. 基于域对象:监听范围围绕 Web 三大域:ServletContext(全局域)、HttpSession(会话域)、ServletRequest(请求域);
  4. 全局生效:配置完成后,整个 Web 应用全局生效,适合做全局统一配置。

3. 常见应用场景

  • 项目启动时:加载配置文件、初始化数据库连接池、创建定时任务;
  • 项目关闭时:释放资源、关闭连接池、记录服务下线日志;
  • 会话监听:统计在线用户数量、用户登录过期销毁;
  • 属性监听:监控域对象中数据的新增、修改、删除操作;
  • 请求监听:统计网站访问量、统一请求日志记录。

二、Servlet 监听器常用接口分类

Servlet 监听器按照监听功能,主要分为两大类型:生命周期监听器属性变化监听器,覆盖三大域对象,核心常用接口如下:

1. 生命周期监听器(监听对象创建与销毁)

负责监听域对象的创建、销毁生命周期事件。

  1. ServletContextListener全局上下文监听器,监听 Web 应用启动初始化项目关闭销毁
  2. HttpSessionListener会话监听器,监听用户 Session 创建失效销毁
  3. ServletRequestListener请求监听器,监听每次 Http 请求创建响应结束销毁

2. 属性变化监听器(监听域内数据变更)

监听域对象中 setAttributeremoveAttribute 引发的属性新增、修改、删除。

  1. ServletContextAttributeListener全局域属性变化监听;
  2. HttpSessionAttributeListener会话域属性变化监听;
  3. ServletRequestAttributeListener请求域属性变化监听。

补充:拓展监听器

除以上基础接口外,还有会话钝化活化、session 绑定监听器等小众接口,日常开发使用频率较低,本文聚焦开发高频常用接口。

三、Servlet 监听器使用步骤 & 代码实战

使用 Servlet 监听器只需要三步:

  1. 自定义监听器类,实现对应监听器接口
  2. 重写接口中的回调方法,编写业务逻辑;
  3. 注册监听器(注解方式 /web.xml 配置方式)。

现代开发推荐使用 @WebListener 注解,简化配置,零 xml 编写。

示例 1:全局上下文监听器(ServletContextListener)

作用:项目启动加载资源,项目关闭释放资源

java

运行

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;

// 注解注册监听器
@WebListener
public class AppContextListener implements ServletContextListener {

    // Web项目启动时执行(容器初始化上下文)
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        System.out.println("===== 项目启动,初始化全局资源 =====");
        // 业务场景:加载配置文件、初始化连接池、读取全局参数
    }

    // Web项目关闭时执行(容器销毁上下文)
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        System.out.println("===== 项目关闭,释放全局资源 =====");
        // 业务场景:关闭线程池、释放数据库连接、保存缓存数据
    }
}

示例 2:会话监听器(HttpSessionListener)

作用:统计在线用户人数

java

运行

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;

@WebListener
public class OnlineUserListener implements HttpSessionListener {

    // Session创建:用户第一次访问服务器,会话建立
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        System.out.println("用户上线,新增会话");
        // 全局计数器+1,统计在线人数
    }

    // Session销毁:会话过期、主动退出、项目重启
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        System.out.println("用户下线,会话销毁");
        // 全局计数器-1
    }
}

示例 3:请求监听器(ServletRequestListener)

作用:统一记录请求访问日志

java

运行

import javax.servlet.annotation.WebListener;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;

@WebListener
public class RequestLogListener implements ServletRequestListener {

    // 请求创建:每次浏览器发起请求触发
    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        System.out.println("收到客户端请求,开始处理");
    }

    // 请求销毁:响应结束,请求对象销毁
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        System.out.println("请求处理完成,响应已返回");
    }
}

示例 4:属性变化监听器(ServletContextAttributeListener)

监听全局域数据新增、修改、删除

java

运行

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;

@WebListener
public class ContextAttrListener implements ServletContextAttributeListener {

    // 新增全局属性
    @Override
    public void attributeAdded(ServletContextAttributeEvent scae) {
        System.out.println("新增全局属性:" + scae.getName() + "=" + scae.getValue());
    }

    // 删除全局属性
    @Override
    public void attributeRemoved(ServletContextAttributeEvent scae) {
        System.out.println("删除全局属性:" + scae.getName());
    }

    // 修改全局属性
    @Override
    public void attributeReplaced(ServletContextAttributeEvent scae) {
        System.out.println("修改全局属性:" + scae.getName());
    }
}

四、两种注册方式说明

1. 注解方式(推荐)

在自定义监听器类上添加 @WebListener 注解,Servlet3.0+ 支持,开发简洁、无需配置文件,主流项目通用。

2. web.xml 配置方式(传统项目)

老旧项目或低版本 Servlet 环境,需要在 web.xml 中手动注册:

xml

<listener>
    <listener-class>com.example.listener.AppContextListener</listener-class>
</listener>

五、监听器执行顺序与注意事项

  1. 执行顺序项目启动:ServletContextListener 初始化请求/会话监听器项目关闭:请求/会话销毁ServletContextListener 销毁

  2. 使用注意点

  • 监听器由容器单例管理,全局唯一,注意多线程并发安全问题;
  • 不要在监听器中编写耗时过长的业务逻辑,避免项目启动缓慢;
  • Session 销毁为被动触发,超时时间可在 web.xml 或 配置类中自定义;
  • 监听器仅作用于当前 Web 应用,无法跨项目监听。

六、总结

  1. Servlet 监听器是 Web 容器的事件监听机制,核心用于监听三大域对象的生命周期与属性变化;
  2. 核心分为生命周期监听属性监听六大常用接口,覆盖项目全生命周期场景;
  3. 开发极简:实现接口 + 重写方法 + @WebListener 注解即可快速使用;
  4. 实际开发中,ServletContextListener 使用率最高,多用于项目初始化与资源释放,是 Web 项目全局配置的核心方案。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值