观察者设计模式
-
在介绍监听器之前,先普及一个知识,观察者设计模式。
-
因为所有的监听器都是观察者设计模式的体现。
-
那什么是观察者设计模式呢?
-
它是事件驱动的一种体现形式。就好比在做什么事情的时候被人盯着,当对应做到某件事时,触发事件。
-
观察者模式通常由以下三部分组成:
- 事件源:触发事件的对象。
- 事件:触发的动作,里面封装了事件源。
- 监听器:当事件源触发事件时,要做的事情。一般是一个接口,由使用者来实现。(此处的思想还涉及了一个涉及模式,我们在JDBC的第二天课程中就给同学们讲解,策略模式)
- 例子:狗发现人从门前过,就会狂吠
-
监听器介绍
- 在程序当中,我们可以对:对象的创建销毁、域对象中属性的变化、会话相关内容进行监听
- Servlet 规范中共计 8 个监听器,监听器都是以接口形式提供,具体功能需要我们自己来完成
监听对象的监听器
1) ServletContextListener
-
ServletContextListener:用于监听 ServletContext 对象的创建和销毁
-
核心方法
返回值 方法名 作用 void contextInitialized(ServletContextEvent sce) 对象创建时执行该方法 void contextDestroyed(ServletContextEvent sce) 对象销毁时执行该方法 - 参数:ServletContextEvent 代表事件对象
- 事件对象中封装了事件源,也就是 ServletContext
- 真正的事件指的是创建或销毁 ServletContext 对象的操作
2) HttpSessionListener
-
HttpSessionListener:用于监听 HttpSession 对象的创建和销毁
-
核心方法
返回值 方法名 作用 void sessionCreated(HttpSessionEvent se) 对象创建时执行该方法 void sessionDestroyed(HttpSessionEvent se) 对象销毁时执行该方法 - 参数:HttpSessionEvent 代表事件对象
- 事件对象中封装了事件源,也就是 HttpSession
- 真正的事件指的是创建或销毁 HttpSession 对象的操作
3) ServletRequestListener
-
ServletRequestListener:用于监听 ServletRequest 对象的创建和销毁
-
核心方法
返回值 方法名 作用 void requestInitialized(ServletRequestEvent sre) 对象创建时执行该方法 void requestDestroyed(ServletRequestEvent sre) 对象销毁时执行该方法 - 参数:ServletRequestEvent 代表事件对象
- 事件对象中封装了事件源,也就是 ServletRequest
- 真正的事件指的是创建或销毁 ServletRequest 对象的操作
监听域对象属性变化的监听器
1) ServletContextAttributeListener
-
ServletContextAttributeListener:用于监听 ServletContext 应用域中属性的变化
-
核心方法
返回值 方法名 作用 void attributeAdded(ServletContextAttributeEvent scae) 域中添加属性时执行该方法 void attributeRemoved(ServletContextAttributeEvent scae) 域中移除属性时执行该方法 void attributeReplaced(ServletContextAttributeEvent scae) 域中替换属性时执行该方法 - 参数:ServletContextAttributeEvent 代表事件对象
- 事件对象中封装了事件源,也就是 ServletContext
- 真正的事件指的是添加、移除、替换应用域中属性的操作
2) HttpSessionAttributeListener
-
HttpSessionAttributeListener:用于监听 HttpSession 会话域中属性的变化
-
核心方法
返回值 方法名 作用 void attributeAdded(ServletSessionBindingEvent se) 域中添加属性时执行该方法 void attributeRemoved(ServletSessionBindingEvent se) 域中移除属性时执行该方法 void attributeReplaced(ServletSessionBindingEvent se) 域中替换属性时执行该方法 - 参数:HttpSessionBindingEvent 代表事件对象
- 事件对象中封装了事件源,也就是 HttpSession
- 真正的事件指的是添加、移除、替换会话域中属性的操作
3) ServletRequestAttributeListener
-
ServletRequestAttributeListener:用于监听 ServletRequest 请求域中属性的变化
-
核心方法
返回值 方法名 作用 void attributeAdded(ServletRequestAttributeEvent srae) 域中添加属性时执行该方法 void attributeRemoved(ServletRequestAttributeEvent srae) 域中移除属性时执行该方法 void attributeReplaced(ServletRequestAttributeEvent srae) 域中替换属性时执行该方法 - 参数:ServletRequestAttributeEvent 代表事件对象
- 事件对象中封装了事件源,也就是 ServletRequest
- 真正的事件指的是添加、移除、替换请求域中属性的操作
监听会话相关的感知性监听器
1) HttpSessionBindingListener
-
HttpSessionBindingListener:用于感知对象和会话域绑定的监听器
-
核心方法
返回值 方法名 作用 void valueBound(HttpSessionBindingEvent event) 数据添加到会话域中(绑定时)执行该方法 void valueUnbound(HttpSessionBindingEvent event) 数据从会话域中移除(解绑时)执行该方法 - 参数:HttpSessionBindingEvent 代表事件对象
- 事件对象中封装了事件源,也就是 HttpSession
- 真正的事件指的是添加、移除会话域中数据的操作
2) HttpSessionActivationListener
-
HttpSessionActivationListener:用于感知会话域中对象钝化和活化的监听器
-
核心方法
返回值 方法名 作用 void sessionWillPassivate(HttpSessionEvent se) 会话域中数据钝化时执行该方法 void sessionDidActivate(HttpSessionEvent se) 会话域中数据活化时执行该方法 - 参数:HttpSessionEvent 代表事件对象
- 事件对象中封装了事件源,也就是 HttpSession
- 真正的事件指的是会话域中数据钝化、活化的操作
监听器的使用
-
在实际开发中,我们可以根据具体情况来从这8个监听器中选择使用
-
感知型监听器由于无需配置,只需要根据实际需求编写代码,所以此处我们就不再演示了
-
我们在剩余6个中分别选择一个监听对象创建销毁和对象域中属性发生变化的监听器演示一下
-
ServletContextListener的使用
/*
ServletContext对象的创建和销毁的监听器
//配置监听器:@WebListener
*/
@WebListener
public class ServletContextListenerDemo implements ServletContextListener{
/*
ServletContext对象创建的时候执行此方法
*/
@Override
public void contextInitialized(ServletContextEvent sce) {
System.out.println("监听到了对象的创建...");
//获取对象
ServletContext servletContext = sce.getServletContext();
System.out.println(servletContext);
}
/*
ServletContext对象销毁的时候执行此方法
*/
@Override
public void contextDestroyed(ServletContextEvent sce) {
System.out.println("监听到了对象的销毁...");
}
}
- ServletContextAttributeListener的使用
/*
应用域对象中的属性变化的监听器
*/
@WebListener
public class ServletContextAttributeListenerDemo implements ServletContextAttributeListener{
/*
向应用域对象中添加属性时执行此方法
*/
@Override
public void attributeAdded(ServletContextAttributeEvent scae) {
System.out.println("监听到了属性的添加...");
//获取应用域对象
ServletContext servletContext = scae.getServletContext();
//获取属性
Object value = servletContext.getAttribute("username");
System.out.println(value);
}
/*
向应用域对象中替换属性时执行此方法
*/
@Override
public void attributeReplaced(ServletContextAttributeEvent scae) {
System.out.println("监听到了属性的替换...");
//获取应用域对象
ServletContext servletContext = scae.getServletContext();
//获取属性
Object value = servletContext.getAttribute("username");
System.out.println(value);
}
/*
向应用域对象中移除属性时执行此方法
*/
@Override
public void attributeRemoved(ServletContextAttributeEvent scae) {
System.out.println("监听到了属性的移除...");
//获取应用域对象
ServletContext servletContext = scae.getServletContext();
//获取属性
Object value = servletContext.getAttribute("username");
System.out.println(value);
}
}
- 修改ServletContextListenerDemo:在contextInitialized中增加如下代码:
//添加属性
servletContext.setAttribute("username","zhangsan");
//替换属性
servletContext.setAttribute("username","lisi");
//移除属性
servletContext.removeAttribute("username");