java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > 监听器Listener详解

JavaWeb三大组件之监听器Listener详解

作者:边境矢梦°

这篇文章主要介绍了JavaWeb三大组件之监听器Listener详解,在JavaWeb应用程序中,Listener监听器是一种机制,用于监听和响应特定的事件,它可以感知并响应与应用程序相关的事件,从而执行相应的逻辑处理,需要的朋友可以参考下

监听器Listener

概念分析 : 

在JavaWeb应用程序中,Listener(监听器)是一种机制,用于监听和响应特定的事件。它可以感知并响应与应用程序相关的事件,从而执行相应的逻辑处理。

事件是在应用程序运行过程中发生的特定动作或状态改变。例如,Web应用程序的启动和关闭、请求的到达和完成、会话的创建和销毁等都被认为是事件。监听器会注册对这些事件的感兴趣,并在事件发生时调用相应的回调方法来执行预定的业务逻辑。

监听器的概念可以类比于现实生活中的观察者模式。在观察者模式中,一个对象(观察者)注册对另一个对象(被观察者)的事件感兴趣,并在被观察者触发相应事件时得到通知并执行相应操作。类似地,在JavaWeb应用程序中,监听器充当观察者的角色,可以监听和响应特定的事件。

通过使用监听器,开发者可以将应用程序的关键行为和状态抽象成事件,并在需要的时候采取相应的措施。比如,在Web应用程序启动时,可以使用ServletContextListener来进行初始化操作;在每次请求到达时,可以使用ServletRequestListener来获取请求信息等。

监听器的设计使得应用程序更加灵活和可扩展。它提供了一种松耦合的方式来解耦应用程序的不同模块,并实现事件驱动的编程模型。监听器是实现Web应用程序的事件处理和扩展性的重要组成部分。

价值所在 : 

监听器(Listener)在JavaWeb应用程序中具有重要的意义和价值,主要体现在以下几个方面:

  1. 实现事件驱动编程:监听器的核心概念是基于事件的触发和响应,它使得开发者可以将应用程序的关键行为和状态抽象成事件,并在事件发生时执行相应的逻辑处理。通过监听器,开发者可以实现事件驱动编程的思想,更加灵活地响应应用程序中的各种事件。
  2. 解耦和模块化:监听器解耦了应用程序中不同模块之间的依赖关系。它提供了一种松耦合的方式来将事件和事件处理的逻辑相互分离,使得不同的模块可以独立地进行开发和维护。通过监听器,开发者可以将特定事件的处理逻辑集中到监听器中,从而提高代码的可读性和可维护性。
  3. 增强可扩展性:使用监听器可以有效地增强应用程序的可扩展性。当应用程序需要添加新的功能或处理新的事件时,可以通过编写自定义的监听器来实现。通过监听器,可以在不修改已有代码的情况下,将新的功能集成到应用程序中,从而实现应用程序的动态扩展。
  4. 提供通用的解决方案:一些监听器是Web容器预先定义的,如ServletContextListener、ServletRequestListener和HttpSessionListener等。这些监听器提供了一些通用的解决方案,可用于应用程序中常见的场景,如应用程序的初始化、请求的处理、会话管理等。通过使用这些通用的监听器,开发者可以以更加快速和方便的方式完成常见功能的实现。

所以它提供了一种事件驱动的编程模型,帮助开发者实现模块间的解耦和功能的扩展,以及提供通用的解决方案。监听器在开发Web应用程序时是一种强大的工具,可以提升代码的可维护性、可扩展性和可读性。

一.  Listener监听器的介绍

1. Listener 监听器它是 JavaWeb 的三大组件之一。 JavaWeb 的三大组件分别是: Servlet 程 序、 Listener 监听器、 Filter 过滤器

2. Listener 是 JavaEE 的规范,就是接口

3. 监听 器的作用是,监听某种变化 ( 一般就是对象创建 / 销毁 , 属性变化 ), 触发对应方法完成 相应的任务

4. JavaWeb 中的监听器(共八个) , 目前最常用的是 ServletContextListener

二. Listener的生命周期

监听器(Listener)在JavaWeb应用程序中起到监听和处理事件的作用。监听器的生命周期与Web应用程序的生命周期密切相关。

  1. ServletContextListener:ServletContextListener会在Web应用程序启动时起作用,并在Web应用程序关闭时销毁。具体来说,当Web容器启动时会触发contextInitialized()方法,开发者可以在这个方法中进行一些初始化操作;当Web容器关闭时会触发contextDestroyed()方法,开发者可以在这个方法中进行一些资源释放、清理操作。
  2. ServletRequestListener:ServletRequestListener会在每次客户端请求到达服务器时起作用,并在服务器响应完成后销毁。具体来说,当客户端发送请求到达服务器时会触发requestInitialized()方法,开发者可以在这个方法中获取和处理请求相关的信息;当服务器响应完成后会触发requestDestroyed()方法,开发者可以在这个方法中进行一些善后操作。
  3. HttpSessionListener:HttpSessionListener会在每次HttpSession创建和销毁时起作用。具体来说,当用户访问Web应用程序时,如果尚未创建HttpSession,会触发sessionCreated()方法,在这个方法中可以进行一些会话管理的操作;当HttpSession被销毁时,会触发sessionDestroyed()方法,在这个方法中可以进行一些会话清理的操作。

注意,监听器是通过在web.xml配置文件中声明来启用的。开发者需要在web.xml文件中添加相应的监听器声明,告诉Web容器要监听哪些事件,并指定相应的监听器类。

总之,监听器的起作用和销毁是在Web应用程序的生命周期中发生的,监听器会在特定的事件发生时被触发,并执行相应的回调方法来处理事件。

三. 常见的监听器

Listener(监听器)可以监听不同的事件,具体监听的事件类型取决于监听器的种类。

在JavaWeb中,常见的监听器都是用于监听Servlet、JSP和Web应用程序中的事件。

下面是一些常见的监听器及其监听的事件类型:

  1. ServletContextListener:监听ServletContext对象的创建和销毁事件,当Web应用程序启动和关闭时触发。
  2. ServletRequestListener:监听ServletRequest对象的创建和销毁事件,在每次客户端请求到达服务器时触发。
  3. HttpSessionListener:监听HttpSession对象的创建和销毁事件,当用户与Web应用程序建立和关闭会话时触发。
  4. ServletContextAttributeListener:监听ServletContext中属性的添加、修改和删除事件。
  5. ServletRequestAttributeListener:监听ServletRequest中属性的添加、修改和删除事件。
  6. HttpSessionAttributeListener:监听HttpSession中属性的添加、修改和删除事件。
  7. HttpSessionActivationListener:监听HttpSession对象的钝化(passivation)和活化(activation)事件,与分布式会话(Distributed Session)有关。
  8. ServletRequestListener:监听ServletContext对象的创建和销毁事件,以及请求的开始和完成。
  9. ServletContextListener:监听ServletContext对象的创建和销毁事件,与Web应用程序的启动和关闭有关。

这只是一部分常见的监听器和事件类型,根据具体需求,你也可以自定义监听器来监听其他类型的事件。

监听器提供了一种机制,让开发者可以在事件发生时执行自定义的逻辑操作,以实现对特定事件的监控和响应。

四. 举例

ServletContextListener

简单的ServletContextListener示例,演示在应用程序启动和关闭时执行初始化和清理操作:

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
 
public class MyServletContextListener implements ServletContextListener {
 
    @Override
    public void contextInitialized(ServletContextEvent sce) {
        // 应用程序启动时执行的初始化操作
        System.out.println("应用程序已启动");
        // 加载配置文件、初始化数据库连接池等
        // ...
    }
 
    @Override
    public void contextDestroyed(ServletContextEvent sce) {
        // 应用程序关闭时执行的清理操作
        System.out.println("应用程序即将关闭");
        // 关闭数据库连接池、释放资源等
        // ...
    }
}

在上面的例子中,MyServletContextListener实现了ServletContextListener接口,并重写了contextInitialized和contextDestroyed方法。

在contextInitialized方法中,你可以执行应用程序启动时的初始化操作,比如加载配置文件、初始化数据库连接池等。

而在contextDestroyed方法中,你可以执行应用程序关闭时的清理操作,比如关闭数据库连接池、释放资源等。

当应用程序启动时,容器将自动调用contextInitialized方法来初始化你的应用程序。当应用程序关闭时,容器将自动调用contextDestroyed方法来执行清理操作。

为了让监听器生效,你还需要在web.xml或使用注解的方式配置监听器的部署描述符,具体的配置方式取决于你使用的Servlet容器。例如,在web.xml中添加以下配置:

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

这样,当应用程序启动或关闭时,MyServletContextListener中的逻辑将被触发执行。

ServletContextAttributeListener

一个简单的ServletContextAttributeListener示例,展示了当ServletContext属性发生变化时执行的操作:

import javax.servlet.ServletContextAttributeEvent;
import javax.servlet.ServletContextAttributeListener;
import javax.servlet.annotation.WebListener;
 
@WebListener
public class MyServletContextAttributeListener implements ServletContextAttributeListener {
 
    @Override
    public void attributeAdded(ServletContextAttributeEvent event) {
        // 当ServletContext属性被添加时执行的操作
        String attributeName = event.getName();
        Object attributeValue = event.getValue();
        System.out.println("ServletContext属性 " + attributeName + " 添加,值为: " + attributeValue);
        // 其他处理逻辑
        // ...
    }
 
    @Override
    public void attributeRemoved(ServletContextAttributeEvent event) {
        // 当ServletContext属性被移除时执行的操作
        String attributeName = event.getName();
        Object attributeValue = event.getValue();
        System.out.println("ServletContext属性 " + attributeName + " 被移除,值为: " + attributeValue);
        // 其他处理逻辑
        // ...
    }
 
    @Override
    public void attributeReplaced(ServletContextAttributeEvent event) {
        // 当ServletContext属性被替换时执行的操作
        String attributeName = event.getName();
        Object oldAttributeValue = event.getValue();
        Object newAttributeValue = event.getServletContext().getAttribute(attributeName);
        System.out.println("ServletContext属性 " + attributeName + " 被替换,旧值为: " + oldAttributeValue + ",新值为: " + newAttributeValue);
        // 其他处理逻辑
        // ...
    }
}

在上面的例子中,MyServletContextAttributeListener实现了ServletContextAttributeListener接口,并使用@WebListener注解标记为一个监听器。它重写了attributeAdded、attributeRemoved和attributeReplaced方法,在这些方法中可以添加对ServletContext属性变化的处理逻辑。

在attributeAdded方法中,当ServletContext属性被添加时,你可以获取属性的名称和值,并执行相应的操作,如记录日志、更新缓存等。

在attributeRemoved方法中,当ServletContext属性被移除时,你可以获取属性的名称和值,并执行相应的操作,如清理资源、撤销缓存等。

在attributeReplaced方法中,当ServletContext属性被替换时,你可以同时获取属性的旧值和新值,并执行相应的操作,如更新缓存、重新加载配置等。

要使监听器生效,你可以使用注解方式将监听器标记为一个@WebListener,这样容器会自动识别和注册监听器。

如果你使用的是web.xml配置文件进行部署描述符的配置,则需要在web.xml中添加以下片段:

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

这样,当ServletContext属性发生变化时,MyServletContextAttributeListener中的相应方法就会被触发执行。

HttpSessionListener

一个简单的HttpSessionListener示例,展示了当HttpSession事件发生时执行的操作:

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
 
@WebListener
public class MyHttpSessionListener implements HttpSessionListener {
 
    @Override
    public void sessionCreated(HttpSessionEvent se) {
        // 当HttpSession被创建时执行的操作
        System.out.println("HttpSession被创建,ID: " + se.getSession().getId());
        // 其他处理逻辑
        // ...
    }
 
    @Override
    public void sessionDestroyed(HttpSessionEvent se) {
        // 当HttpSession被销毁时执行的操作
        System.out.println("HttpSession被销毁,ID: " + se.getSession().getId());
        // 其他处理逻辑
        // ...
    }
}

在上述示例中,MyHttpSessionListener实现了HttpSessionListener接口,并使用@WebListener注解标记为一个监听器。它重写了sessionCreated和sessionDestroyed方法,在这些方法中可以添加对HttpSession事件的处理逻辑。

在sessionCreated方法中,当HttpSession被创建时,你可以获取HttpSession的ID,并执行相应的操作,如记录日志、初始化用户会话数据等。

在sessionDestroyed方法中,当HttpSession被销毁时,你可以获取HttpSession的ID,并执行相应的操作,如清理资源、保存用户会话状态等。

要使监听器生效,你可以使用注解方式将监听器标记为一个@WebListener,这样容器会自动识别和注册监听器。如果你使用的是web.xml配置文件进行部署描述符的配置,则需要在web.xml中添加以下片段:

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

这样,当HttpSession事件发生时,MyHttpSessionListener中的相应方法就会被触发执行。

HttpSessionAttributeListener

一个简单的HttpSessionAttributeListener示例,展示了当HttpSession属性发生变化时执行的操作:

import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionAttributeListener;
import javax.servlet.http.HttpSessionBindingEvent;
 
@WebListener
public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener {
 
    @Override
    public void attributeAdded(HttpSessionBindingEvent event) {
        // 当向HttpSession中添加属性时执行的操作
        System.out.println("属性已添加:名称:" + event.getName() + ",值:" + event.getValue());
        // 其他处理逻辑
        // ...
    }
 
    @Override
    public void attributeRemoved(HttpSessionBindingEvent event) {
        // 当从HttpSession中移除属性时执行的操作
        System.out.println("属性已移除:名称:" + event.getName() + ",值:" + event.getValue());
        // 其他处理逻辑
        // ...
    }
 
    @Override
    public void attributeReplaced(HttpSessionBindingEvent event) {
        // 当替换HttpSession中的属性时执行的操作
        System.out.println("属性已替换:名称:" + event.getName() + ",旧值:" + event.getValue() + ",新值:" + event.getSession().getAttribute(event.getName()));
        // 其他处理逻辑
        // ...
    }
}

在上述示例中,MyHttpSessionAttributeListener实现了HttpSessionAttributeListener接口,并使用@WebListener注解标记为一个监听器。它重写了attributeAdded、attributeRemoved和attributeReplaced方法,在这些方法中可以添加对HttpSession属性变化的处理逻辑。

在attributeAdded方法中,当向HttpSession中添加属性时,你可以获取属性的名称和值,并执行相应的操作,如记录日志、更新相关数据等。

在attributeRemoved方法中,当从HttpSession中移除属性时,你可以获取属性的名称和值,并执行相应的操作,如记录日志、清除相关数据等。

在attributeReplaced方法中,当替换HttpSession中的属性时,你可以获取属性的名称、旧值和新值,并执行相应的操作,如记录日志、更新相关数据等。

要使监听器生效,你可以使用注解方式将监听器标记为一个@WebListener。

如果你使用的是web.xml配置文件进行部署描述符的配置,则需要在web.xml中添加以下片段:

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

这样,当HttpSession属性发生变化时,MyHttpSessionAttributeListener中的相应方法就会被触发执行。

ServletRequestListener

一个简单的ServletRequestListener示例,展示了在每个页面请求到达和处理完成时执行的操作:

import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
 
@WebListener
public class MyServletRequestListener implements ServletRequestListener {
 
    @Override
    public void requestInitialized(ServletRequestEvent sre) {
        // 页面请求到达时执行的操作
        System.out.println("收到新请求");
        // 记录请求信息,如URL、参数等
        // ...
    }
 
    @Override
    public void requestDestroyed(ServletRequestEvent sre) {
        // 页面请求处理完成后执行的操作
        System.out.println("请求处理完成");
        // 清理操作,如释放资源
        // ...
    }
}

在上面的例子中,MyServletRequestListener实现了ServletRequestListener接口,并使用@WebListener注解标记为一个监听器。它重写了requestInitialized和requestDestroyed方法,在这两个方法中可以添加自定义的逻辑处理。

在requestInitialized方法中,你可以记录请求信息,如URL、参数等。

在requestDestroyed方法中,你可以执行清理操作,如释放资源。

要让监听器生效,你可以使用注解方式将监听器标记为一个@WebListener,这样容器会自动识别和注册监听器。

如果你使用的是web.xml配置文件进行部署描述符的配置,则需要在web.xml中添加以下片段:

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

这样,在每次页面请求到达时,MyServletRequestListener中的逻辑将被触发执行。同样,在每个页面请求完成后,requestDestroyed方法也会被调用执行清理操作。

ServletRequestAttributeListener

一个简单的ServletRequestAttributeListener示例,展示了当ServletRequest属性发生变化时执行的操作:

import javax.servlet.ServletRequestAttributeEvent;
import javax.servlet.ServletRequestAttributeListener;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpServletRequest;
 
@WebListener
public class MyServletRequestAttributeListener implements ServletRequestAttributeListener {
 
    @Override
    public void attributeAdded(ServletRequestAttributeEvent event) {
        // 当向ServletRequest中添加属性时执行的操作
        HttpServletRequest request = (HttpServletRequest) event.getServletRequest();
        System.out.println("属性已添加:名称:" + event.getName() + ",值:" + event.getValue() + ",请求URL:" + request.getRequestURL());
        // 其他处理逻辑
        // ...
    }
 
    @Override
    public void attributeRemoved(ServletRequestAttributeEvent event) {
        // 当从ServletRequest中移除属性时执行的操作
        HttpServletRequest request = (HttpServletRequest) event.getServletRequest();
        System.out.println("属性已移除:名称:" + event.getName() + ",值:" + event.getValue() + ",请求URL:" + request.getRequestURL());
        // 其他处理逻辑
        // ...
    }
 
    @Override
    public void attributeReplaced(ServletRequestAttributeEvent event) {
        // 当替换ServletRequest中的属性时执行的操作
        HttpServletRequest request = (HttpServletRequest) event.getServletRequest();
        System.out.println("属性已替换:名称:" + event.getName() + ",旧值:" + event.getValue() + ",新值:" + request.getAttribute(event.getName()) + ",请求URL:" + request.getRequestURL());
        // 其他处理逻辑
        // ...
    }
}

在上述示例中,MyServletRequestAttributeListener实现了ServletRequestAttributeListener接口,并使用@WebListener注解标记为一个监听器。它重写了attributeAdded、attributeRemoved和attributeReplaced方法,在这些方法中可以添加对ServletRequest属性变化的处理逻辑。

在attributeAdded方法中,当向ServletRequest中添加属性时,你可以获取属性的名称和值,并执行相应的操作,如记录日志、更新相关数据等。通过event.getServletRequest()可以获取到HttpServletRequest对象,进而可以获取请求的URL等信息。

在attributeRemoved方法中,当从ServletRequest中移除属性时,你可以获取属性的名称和值,并执行相应的操作,如记录日志、清除相关数据等。同样,可以通过event.getServletRequest()获取到HttpServletRequest对象。

在attributeReplaced方法中,当替换ServletRequest中的属性时,你可以获取属性的名称、旧值和新值,并执行相应的操作,如记录日志、更新相关数据等。同样,通过event.getServletRequest()可以获取到HttpServletRequest对象。

要使监听器生效,你可以使用注解方式将监听器标记为一个@WebListener。

如果你使用的是web.xml配置文件进行部署描述符的配置,则需要在web.xml中添加以下片段:

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

这样,当ServletRequest属性发生变化时,MyServletRequestAttributeListener中的相应方法就会被触发执行。

五. 打开一个Tomcat应用

在启动Tomcat并自动打开index.jsp页面的过程中,以下监听器将执行相应的操作:

  1. ServletContextListener:
    • contextInitialized 方法将在Tomcat启动时执行,你可以在此方法中执行应用程序启动时的初始化操作,例如加载配置文件、初始化数据库连接池等。
    • contextDestroyed 方法将在Tomcat关闭时执行,你可以在此方法中执行应用程序关闭时的清理操作,例如关闭数据库连接池、释放资源等。
  2. ServletRequestListener:
    • requestInitialized 方法将在每个页面请求到达Tomcat时执行,你可以在此方法中记录请求信息,如URL、参数等。
    • requestDestroyed 方法将在每个页面请求处理完成后执行,你可以在此方法中执行清理操作,如释放资源等。
  3. HttpSessionListener:
    • sessionCreated 方法将在每个新的会话被创建时执行,你可以在此方法中记录用户登录信息、初始化权限等。
    • sessionDestroyed 方法将在每个会话被销毁时执行,你可以在此方法中执行清理会话相关资源、处理用户退出等操作。

当你在浏览器访问Tomcat的根目录(如 //localhost:8080/)时,以下是一种可能的监听器执行顺序:

  1. ServletContextListener 的 contextInitialized 方法将被调用。
    • 在这个方法中,你可以执行应用程序启动时的初始化操作,如加载配置文件、初始化数据库连接池等。
  2. ServletRequestListener 的 requestInitialized 方法将被调用。
    • 在这个方法中,你可以记录请求信息,如URL、参数等。
  3. Tomcat 将查找并处理index.jsp页面。
  4. ServletRequestListener 的 requestDestroyed 方法将被调用。
    • 在这个方法中,你可以执行清理操作,如释放资源等。
  5. HttpSessionListener 的 sessionCreated 方法将被调用(如果启用了会话)。
    • 在这个方法中,你可以记录用户登录信息、初始化权限等。
  6. 页面加载完成并在浏览器中呈现。

注意,具体的监听器执行顺序可能会根据Tomcat版本、配置和其他因素而有所不同。此外,如果你在应用程序中有自定义的监听器,那么它们也会参与监听器的执行顺序。

到此这篇关于JavaWeb三大组件之监听器Listener详解的文章就介绍到这了,更多相关监听器Listener详解内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文