Listener(监听器)的使用
1,监听器的介绍
监听器(Listener)是一个专门用于对其他对象身上发生的事件或状态改变进行监听和相应处理的对象,当被监视的对象发生情况时,立即采取相应的行动。监听器是一个实现特定接口的普通Java程序,这个程序专门用于监听另一个Java对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法立即被执行。
监听器的一些相关术语:事件源、事件监听器、事件对象、响应行为。(我们形象的用:狗仔监视某明星出轨 来理解一下)
术语 | 描述 |
---|---|
事件源 | 被监听的对象(可以理解为明星) |
事件监听器 | 监听事件源对象,事件源对象的状态的变化都会触发监听器(狗仔) |
事件对象 | 将监听器与事件源进行绑定(明星出轨) |
响应行为 | 监听器监听到事件源的状态变化时 所涉及的功能代码(狗仔做出的动作,发布明星出轨信息) |
2、监听器的分类
在JavaWeb中的监听器就是监听域中对象的状态。它们监听的分别是ServletContext域、Session域、Request域这三类。
它们按监听的对象划分为三类:
- ServletContext对象,监听器为ServletContextListener
- HttpSession对象,监听器为HttpSessionListener
- ServletRequest对象,监听器为ServletRequestListener
按监听的内容划分为两类:
- 监听域对象的创建与销毁
- 监听域对象的属性变化
整合如下图:
ServletContext域 | HttpSession域 | ServletRequest域 | |
---|---|---|---|
域对象的创建于销毁 | ServletContextListener | HttpSessionListener | ServletRequestListener |
域对象内的属性变化 | ServletContextAttributeListener | HttpSessionAttributeListener | ServletRequestAttributeListener |
3、监听ServletContext域对象的创建和销毁
ServletContextListener接口用于监听ServletContext对象的创建和销毁事件。实现了ServletContextListener接口的类都可以对ServletContext对象的创建和销毁进行监听。当ServletContext对象被创建时,激发contextInitialized (ServletContextEvent sce)方法。当ServletContext对象被销毁时,激发contextDestroyed(ServletContextEvent sce)方法。
ServletContext域对象创建和销毁时机:
- 创建:服务器启动针对每一个Web应用创建ServletContext。
- 销毁:服务器关闭前先关闭代表每一个web应用的ServletContext。
示例:编写一个MyServletContextListener类,实现ServletContextListener接口,监听ServletContext对象的创建和销毁。
监听器创建的分为三个步骤如下:
- 编写一个监听器类去实现监听器接口。
- 重写监听器的方法。
- 在web.xml中配置监听器。
举例代码如下所示:
①、编写监听器,并且重写监听器的方法,其代码如下:
package com.thr;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* @author tanghaorong
* @date 2020-05-07
* @desc 监听ServletContext域对象的创建和销毁
*/
public class MyServletContextListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext对象创建");
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
System.out.println("ServletContext对象销毁");
}
}
②、在web.xml文件中注册监听器。如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 注册针对ServletContext对象进行监听的监听器 -->
<listener>
<description>ServletContextListener监听器</description>
<!--实现了ServletContextListener接口的监听器类 -->
<listener-class>com.thr.MyServletContextListener</listener-class>
</listener>
</web-app>
在web.xml中配置监听器时要注意它们的先后顺序:监听器>过滤器>Serlvet。
当然我们也可以使用注解——@WebListener。它的内部参数就一个value,所以一般直接写一个@WebListener就可以了。例如:
/**
* @author tanghaorong
* @date 2020-05-07
* @desc 使用注解监听ServletContext域对象的创建和销毁
*/
@WebListener
public class MyServletContextListener implements ServletContextListener {
code...
}
4、监听HttpSession域对象的创建和销毁
HttpSessionListener 接口用于监听HttpSession对象的创建和销毁。在创建一个Session时,激发sessionCreated (HttpSessionEvent se) 方法。在销毁一个Session时,激发sessionDestroyed (HttpSessionEvent se) 方法。
HttpSession域对象创建和销毁时机:
- 创建:服务器第一次访问Servlet时,调用getSession()方法的时候. 如果访问的是jsp则直接创建。
- 销毁:自动销毁:session过期了(默认30分钟);手动销毁:session.invalidate()或在xml中配置;强制销毁:非正常关闭服务器(正常关闭序列化到硬盘)。
范例:编写一个MyHttpSessionListener类,实现HttpSessionListener接口,监听HttpSession对象的创建和销毁。
①、编写监听器,这里直接使用注解配置,免得再去web.xml配置了。代码如下:
package com.thr;
import javax.servlet.annotation.WebListener;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
/**
* @author tanghaorong
* @date 2020-05-08
* @desc 监听Session域对象的创建和销毁
*/
@WebListener
public class MyHttpSessionListener implements HttpSessionListener {
@Override
public void sessionCreated(HttpSessionEvent httpSessionEvent) {
System.out.println(httpSessionEvent.getSession() + "创建了!!");
}
@Override
public void sessionDestroyed(HttpSessionEvent httpSessionEvent) {
System.out.println("session销毁了!!");
}
}
注意:HttpSession的销毁时机需要在web.xml中进行配置,如下:
<session-config>
<!--配置HttpSession对象的1分钟之后销毁 -->
<session-timeout>1</session-timeout>
</session-config>
然后当我们访问jsp页面时,HttpSession对象就会创建。
运行结果如下:
过来一分钟之后。
5、监听ServletRequest域对象的创建和销毁
ServletRequestListener接口用于监听ServletRequest 对象的创建和销毁。当Request对象被创建时,监听器的requestInitialized(ServletRequestEvent sre)方法将会被调用。当Request对象被销毁时,监听器的requestDestroyed(ServletRequestEvent sre)方法将会被调用
ServletRequest域对象创建和销毁时机:
- 创建:用户每一次访问都会创建request对象
- 销毁:当前访问结束,request对象就会销毁
范例:编写一个MyServletRequestListener类,实现ServletRequestListener接口,监听ServletRequest对象的创建和销毁
①、编写监听器,代码如下:
package com.thr;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
import javax.servlet.annotation.WebListener;
/**
* @author tanghaorong
* @date 2020-05-08
* @desc 监听ServletRequest域对象的创建和销毁
*/
@WebListener
public class MyServletRequestListener implements ServletRequestListener {
@Override
public void requestDestroyed(ServletRequestEvent servletRequestEvent) {
System.out.println(servletRequestEvent.getServletRequest() + "销毁了!!");
}
@Override
public void requestInitialized(ServletRequestEvent servletRequestEvent) {
System.out.println(servletRequestEvent.getServletRequest() + "创建了!!");
}
}
测试结果如下:
从运行结果中可以看到,用户每一次访问都会创建request对象,当访问结束后,request对象就会销毁。