SpringBoot–基础–6.3–servlet的3大组件–监听器
代码位置
https://gitee.com/DanShenGuiZu/learnDemo/tree/mysql_mybaties_DB/springboot-learn/springboot-4
1、监听器
- 实现特定接口的普通java程序
- 专门用于监听另一个对象的方法调用或属性改变,当被监听对象发生上述事件后,监听器某个方法将立即被执行。
1.1、原理图
1.2、事件源划分(三个域对象)
- ServletContext
- HttpSession
- ServletRequest
2、事件源对应的监听器
2.1、监听三个域对象创建和销毁的事件监听器
2.1.1、ServletContextListener 接口
- 用于监听 ServletContext 对象的创建和销毁事件。
- 当 ServletContext 对象被创建时:激发contextInitialized(ServletContextEvent sce)方法
- 当 ServletContext 对象被销毁时:激发contextDestroyed(ServletContextEvent sce)方法
2.1.2、HttpSessionListener接口
- 用于监听HttpSession的创建和销毁
- 创建一个Session时:sessionCreated(HttpSessionEvent se)方法将会被调用。
- 销毁一个Session时:sessionDestroyed(HttpSessionEvent se)方法将会被调用。
- 销毁HttpSession不精确。
2.1.3、ServletRequestListener 接口
- 用于监听ServletRequest 对象的创建和销毁。
- Request对象被创建时:监听器的requestInitialized方法将会被调用。
- Request对象被销毁时:监听器的requestDestroyed方法将会被调用。
2.2、监听域对象中属性的增加和删除的事件监听器
- 对应的接口
- ServletContextAttributeListener
- HttpSessionAttributeListener
- ServletRequestAttributeListener
- 这三个接口中都定义了三个方法来处理被监听对象中的属性的增加,删除和替换的事件,
- 同一个事件在这三个接口中对应的方法名称完全相同,只是接受的参数类型不同
2.2.1、attributeAdded 方法
当向被监听器对象中增加一个属性时,web容器就调用事件监听器的 attributeAdded 方法进行操作,这个方法接受一个事件类型的参数,监听器可以通过这个参数来获得正在增加属性的域对象和被保存到域中的属性对象
各个域属性监听器中的完整语法定义为:
public void attributeAdded(ServletContextAttributeEvent scae)
public void attributeReplaced(HttpSessionBindingEvent hsbe)
public void attributeRmoved(ServletRequestAttributeEvent srae)
2.2.2、attributeRemoved 方法
当删除被监听对象中的一个属性时,web容器调用事件监听器的这个方法
各个域属性监听器中的完整语法定义为:
public void attributeRemoved(ServletContextAttributeEvent scae)
public void attributeRemoved(HttpSessionBindingEvent hsbe)
public void attributeRemoved(ServletRequestAttributeEvent srae)
2.2.3、attributeReplaced 方法
当监听器的域对象中的某个属性被替换时,web容器调用事件监听器的这个方法
各个域属性监听器中的完整语法定义为:
public void attributeReplaced(ServletContextAttributeEvent scae)
public void attributeReplaced(HttpSessionBindingEvent hsbe)
public void attributeReplaced(ServletRequestAttributeEvent srae)
2.3、监听绑定到HttpSession 域中的某个对象的状态的事件监听器
Servlet 规范中定义了两个特殊的监听器接口来帮助 JavaBean 对象了解自己在Session 域中的这些状态
HttpSessionBindingListener和HttpSessionActivationListener接口 ,实现这两个接口的类不需要 web.xml 文件中进行注册,因为事件源和监听器都是JavaBean自身。
2.3.1、HttpSessionBindingListener接口
2.3.1.1、当对象被绑定到 HttpSession 对象中时:
web 服务器调用该对象的 void valueBound(HttpSessionBindingEvent event)方法
2.3.1.2、当对象从 HttpSession 对象中解除绑定时:
web 服务器调用该对象的 void valueUnbound(HttpSessionBindingEvent event)方法
2.3.2、HttpSessionActivationListener接口
2.3.2.1、sessionWillPassivate(HttpSessionBindingEventevent)方法
当绑定到HttpSession对象中的对象将要随HttpSession对象被钝化之前,web服务器调用
2.3.2.2、sessionDidActive(HttpSessionBindingEvent event)方法
当绑定到 HttpSession 对象中的对象将要随 HttpSession 对象被活化之后,web 服务器调用
2.4、Servlet 监听器
- 一个 web.xml 文件中可以配置多个 Servlet 事件监听器
- web 服务器按照它们在 web.xml 文件中的注册顺序来加载和注册这些 Serlvet 事件监听器。
3、监听器的工作过程和生命周期
3.1、开发过程:
- 写一个普通类实现对应的接口,即事件监听器
- 在web.xml文件中注册事件监听器
<!-- 事件源注册事件监听器,由容器完成 -->
<listener>
<listener-class>cn.itcast.web.listener.MyServletContextListener</listener-class>
</listener>
3.2、生命周期:
空参构造(1次)->初始化(1次)->销毁化(1次),是一个单例的模式
在部署web应用是产生,即用户第一次访问之前已经产生,在重新部署web应用时,后销毁原监听器,再产生新的监听器
3.3、案例
监听器,用于监听HttpSesison产生和销毁
web.xml
<listener>
<listener-class>cn.xxx.web.listener.MyHttpSessionListener</listener-class>
</listener>
代码
//监听器[用于监听HttpSesison产生和销毁]
public class MyHttpSessionListener implements HttpSessionListener {
//产生
public void sessionCreated(HttpSessionEvent se){
HttpSession session = se.getSession();
System.out.println(session.getId());
System.out.println("sessionCreated()" + new Date().toLocaleString());
}
//销毁
public void sessionDestroyed(HttpSessionEvent se){
HttpSession session = se.getSession();
System.out.println(session.getId());
System.out.println("sessionDestroyed()" + new Date().toLocaleString());
}
}
测试
客户端发起一个server请求
54DF50C7F845D62660348E129401A2FD
sessionCreated()2018-9-26 19:53:43
4、自定义一个监听器
4.1、代码结构
4.2、代码
EventConfig
@Configuration
//定义一个 Component注解的扫描范围
@ComponentScan("fei.zhou.springboot4.demo6")
public class EventConfig {
}
EventPublisher
/**
* 事件发布器,就是一个工具类
*
*/
@Component
public class EventPublisher {
@Autowired
ApplicationContext applicationContext;
// 发布事件
public void publish(ApplicationEvent event) {
// 发布事件
applicationContext.publishEvent(event);
}
}
LoginEvent
/**
* 定义一个登陆事件,用于被发布
*
*/
public class LoginEvent extends ApplicationEvent {
private static final long serialVersionUID = 1L;
//定义事件里面的对象,用于参数传递
public String message;
public LoginEvent(Object source, String message) {
super(source);
this.message = message;
}
}
LoginEventListener
/**
* 登陆事件监听,当有登陆事件触发的时候,执行这里的代码
*
*/
@Component
public class LoginEventListener implements ApplicationListener<LoginEvent> {// 设置要监听的类
@Override
// 对监听对象进行处理
public void onApplicationEvent(LoginEvent event) {
// 被监听的对象
String msg = event.message;
System.out.println("LoginEventListener 监听到登陆事件》登陆的消息是:" + msg);
}
}
Test
public class Test {
public static void main(String[] args) {
// 获取上线文
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(EventConfig.class);
// 获取 事件发布器,就是一个工具类
EventPublisher eventPublisher = context.getBean(EventPublisher.class);
// 创建登陆事件
LoginEvent loginEvent = new LoginEvent(eventPublisher, "小苗登陆了");
// 发布事件
eventPublisher.publish(loginEvent);
//关闭上下文
context.close();
}
}
5、注册Listener 案例
5.1、常用监听
- ServletContextListener : 监听servletContext对象的创建以及销毁
- HttpSessionListener : 监听session对象的创建以及销毁
- ServletRequestListener : 监听request对象的创建以及销毁
- ServletContextAttributeListener : 监听servletContext对象中属性的改变
- HttpSessionAttributeListener : 监听session对象中属性的改变
- ServletRequestAttributeListener : 监听request对象中属性的改变
5.2、代码和测试结果
ListenerConfig
package fei.zhou.springboot4.business.config.listener;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 描述该类- JPA
*
* @author zhoufei
* @class: ListenerConfig
* @date 2021/1/20 11:00
* @Verson 1.0 -2021/1/20 11:00
* @see
*/
@Configuration
public class ListenerConfig {
// 注册监听
@Bean
public ServletListenerRegistrationBean myListener() {
ServletListenerRegistrationBean<MyListener> registrationBean = new ServletListenerRegistrationBean<>(
new MyListener());
return registrationBean;
}
}
MyListener
package fei.zhou.springboot4.business.config.listener;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
/**
* 监听Servlet上下文
*
* @author zhoufei
* @class: MyListener
* @date 2021/1/20 11:00
* @Verson 1.0 -2021/1/20 11:00
* @see
*/
public class MyListener implements ServletContextListener {
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("Servlet上下文---->当前web项目启动");
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("Servlet上下文---->当前web项目销毁");
}
}
```