大学生涯springListeners In Java
Jie一. 监听器概述
1. 监听器的定义
监听器:专门用于对域对象对象身上发生的事件或状态改变进行监听和相应处理的对象
监听器是GOF设计模式中,观察者模式的典型案例
观察者模式: 当被观察的对象发生某些改变时, 观察者自动采取对应的行动的一种设计模式
监听器使用的感受类似JS中的事件,被观察的对象发生某些情况时,自动触发代码的执行
监听器并不监听web项目中的所有组件,仅仅是对三大域对象做相关的事件监听
2. 监听器的分类
web中定义八个监听器接口
作为监听器的规范
,这八个接口按照不同的标准
可以形成不同的
分类
按监听的对象划分
- application域监听器 ServletContextListener ServletContextAttributeListener
- session域监听器 HttpSessionListener HttpSessionAttributeListener HttpSessionBindingListener HttpSessionActivationListener
- request域监听器 ServletRequestListener ServletRequestAttributeListener
按监听的事件分
- 域对象的创建和销毁监听器 ServletContextListener HttpSessionListener ServletRequestListener
- 域对象数据增删改事件监听器 ServletContextAttributeListener HttpSessionAttributeListener ServletRequestAttributeListener
- 其他监听器 HttpSessionBindingListener HttpSessionActivationListener
二. 监听器的六个主要接口
1 application域监听器
ServletContextListener 监听ServletContext对象的创建与销毁
方法名 | 作用 |
---|
contextInitialized(ServletContextEvent sce) | ServletContext创建时调用 |
contextDestroyed(ServletContextEvent sce) | ServletContext销毁时调用 |
- ServletContextEvent对象代表从ServletContext对象身上捕获到的事件,通过这个事件对象我们可以获取到ServletContext对象。
ServletContextAttributeListener 监听ServletContext中属性的添加、移除和修改
方法名 | 作用 |
---|
attributeAdded(ServletContextAttributeEvent scab) | 向ServletContext中添加属性时调用 |
attributeRemoved(ServletContextAttributeEvent scab) | 从ServletContext中移除属性时调用 |
attributeReplaced(ServletContextAttributeEvent scab) | 当ServletContext中的属性被修改时调用 |
- ServletContextAttributeEvent对象代表属性变化事件,它包含的方法如下:
方法名 | 作用 |
---|
getName() | 获取修改或添加的属性名 |
getValue() | 获取被修改或添加的属性值 |
getServletContext() | 获取ServletContext对象 |
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| package com.atguigu.listeners;
import jakarta.servlet.*; import jakarta.servlet.annotation.WebListener;
@WebListener public class ApplicationListener implements ServletContextListener , ServletContextAttributeListener { @Override public void contextInitialized(ServletContextEvent sce) { ServletContext application = sce.getServletContext(); System.out.println("application"+application.hashCode()+" initialized"); } @Override public void contextDestroyed(ServletContextEvent sce) { ServletContext application = sce.getServletContext(); System.out.println("application"+application.hashCode()+" destroyed"); }
@Override public void attributeAdded(ServletContextAttributeEvent scae) { String name = scae.getName(); Object value = scae.getValue(); ServletContext application = scae.getServletContext(); System.out.println("application"+application.hashCode()+" add:"+name+"="+value); }
@Override public void attributeRemoved(ServletContextAttributeEvent scae) { String name = scae.getName(); Object value = scae.getValue(); ServletContext application = scae.getServletContext(); System.out.println("application"+application.hashCode()+" remove:"+name+"="+value); } @Override public void attributeReplaced(ServletContextAttributeEvent scae) { String name = scae.getName(); Object value = scae.getValue(); ServletContext application = scae.getServletContext(); Object newValue = application.getAttribute(name); System.out.println("application"+application.hashCode()+" change:"+name+"="+value+" to "+newValue); }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| @WebServlet(urlPatterns = "/servletA",name = "servletAName") public class ServletA extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext application = this.getServletContext(); application.setAttribute("k1","v1"); application.setAttribute("k2","v2"); } }
@WebServlet(urlPatterns = "/servletB", name = "servletBName") public class ServletB extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { ServletContext appliation = getServletContext(); appliation.setAttribute("k1","value1"); appliation.removeAttribute("k2"); } }
|
2. session域监听器
HttpSessionListener 监听HttpSession对象的创建与销毁
方法名 | 作用 |
---|
sessionCreated(HttpSessionEvent hse) | HttpSession对象创建时调用 |
sessionDestroyed(HttpSessionEvent hse) | HttpSession对象销毁时调用 |
- HttpSessionEvent对象代表从HttpSession对象身上捕获到的事件,通过这个事件对象我们可以获取到触发事件的HttpSession对象。
HttpSessionAttributeListener 监听HttpSession中属性的添加、移除和修改
方法名 | 作用 |
---|
attributeAdded(HttpSessionBindingEvent se) | 向HttpSession中添加属性时调用 |
attributeRemoved(HttpSessionBindingEvent se) | 从HttpSession中移除属性时调用 |
attributeReplaced(HttpSessionBindingEvent se) | 当HttpSession中的属性被修改时调用 |
- HttpSessionBindingEvent对象代表属性变化事件,它包含的方法如下:
方法名 | 作用 |
---|
getName() | 获取修改或添加的属性名 |
getValue() | 获取被修改或添加的属性值 |
getSession() | 获取触发事件的HttpSession对象 |
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
| package com.atguigu.listeners;
import jakarta.servlet.*; import jakarta.servlet.annotation.WebListener; import jakarta.servlet.http.*;
@WebListener public class SessionListener implements HttpSessionListener, HttpSessionAttributeListener { @Override public void sessionCreated(HttpSessionEvent se) { HttpSession session = se.getSession(); System.out.println("session"+session.hashCode()+" created"); }
@Override public void sessionDestroyed(HttpSessionEvent se) { HttpSession session = se.getSession(); System.out.println("session"+session.hashCode()+" destroyed"); } @Override public void attributeAdded(HttpSessionBindingEvent se) { String name = se.getName(); Object value = se.getValue(); HttpSession session = se.getSession(); System.out.println("session"+session.hashCode()+" add:"+name+"="+value); } @Override public void attributeRemoved(HttpSessionBindingEvent se) { String name = se.getName(); Object value = se.getValue(); HttpSession session = se.getSession(); System.out.println("session"+session.hashCode()+" remove:"+name+"="+value); } @Override public void attributeReplaced(HttpSessionBindingEvent se) { String name = se.getName(); Object value = se.getValue(); HttpSession session = se.getSession(); Object newValue = session.getAttribute(name); System.out.println("session"+session.hashCode()+" change:"+name+"="+value+" to "+newValue); }
}
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| @WebServlet(urlPatterns = "/servletA",name = "servletAName") public class ServletA extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession();
session.setAttribute("k1","v1"); session.setAttribute("k2","v2"); } }
@WebServlet(urlPatterns = "/servletB", name = "servletBName") public class ServletB extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(); session.setAttribute("k1","value1"); session.removeAttribute("k2"); session.invalidate(); } }
|
3. request域监听器
ServletRequestListener 监听ServletRequest对象的创建与销毁
方法名 | 作用 |
---|
requestInitialized(ServletRequestEvent sre) | ServletRequest对象创建时调用 |
requestDestroyed(ServletRequestEvent sre) | ServletRequest对象销毁时调用 |
- ServletRequestEvent对象代表从HttpServletRequest对象身上捕获到的事件,通过这个事件对象我们可以获取到触发事件的HttpServletRequest对象。另外还有一个方法可以获取到当前Web应用的ServletContext对象。
ServletRequestAttributeListener 监听ServletRequest中属性的添加、移除和修改
方法名 | 作用 |
---|
attributeAdded(ServletRequestAttributeEvent srae) | 向ServletRequest中添加属性时调用 |
attributeRemoved(ServletRequestAttributeEvent srae) | 从ServletRequest中移除属性时调用 |
attributeReplaced(ServletRequestAttributeEvent srae) | 当ServletRequest中的属性被修改时调用 |
- ServletRequestAttributeEvent对象代表属性变化事件,它包含的方法如下:
方法名 | 作用 |
---|
getName() | 获取修改或添加的属性名 |
getValue() | 获取被修改或添加的属性值 |
getServletRequest () | 获取触发事件的ServletRequest对象 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50
| package com.atguigu.listeners;
import jakarta.servlet.*; import jakarta.servlet.annotation.WebListener;
@WebListener public class RequestListener implements ServletRequestListener , ServletRequestAttributeListener { @Override public void requestInitialized(ServletRequestEvent sre) { ServletRequest request = sre.getServletRequest(); System.out.println("request"+request.hashCode()+" initialized"); }
@Override public void requestDestroyed(ServletRequestEvent sre) { ServletRequest request = sre.getServletRequest(); System.out.println("request"+request.hashCode()+" destoryed"); }
@Override public void attributeAdded(ServletRequestAttributeEvent srae) { String name = srae.getName(); Object value = srae.getValue(); ServletRequest request = srae.getServletRequest(); System.out.println("request"+request.hashCode()+" add:"+name+"="+value); }
@Override public void attributeRemoved(ServletRequestAttributeEvent srae) { String name = srae.getName(); Object value = srae.getValue(); ServletRequest request = srae.getServletRequest(); System.out.println("request"+request.hashCode()+" remove:"+name+"="+value); } @Override public void attributeReplaced(ServletRequestAttributeEvent srae) { String name = srae.getName(); Object value = srae.getValue(); ServletRequest request = srae.getServletRequest(); Object newValue = request.getAttribute(name); System.out.println("request"+request.hashCode()+" change:"+name+"="+value+" to "+newValue); } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| @WebServlet(urlPatterns = "/servletA",name = "servletAName") public class ServletA extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setAttribute("k1","v1"); req.setAttribute("k2","v2"); req.getRequestDispatcher("servletB").forward(req,resp); } }
@WebServlet(urlPatterns = "/servletB", name = "servletBName") public class ServletB extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { req.setAttribute("k1","value1"); req.removeAttribute("k2");
} }
|
三. session域的两个特殊监听器
1. session绑定监听器
HttpSessionBindingListener 监听当前监听器对象在Session域中的增加与移除
方法名 | 作用 |
---|
valueBound(HttpSessionBindingEvent event) | 该类的实例被放到Session域中时调用 |
valueUnbound(HttpSessionBindingEvent event) | 该类的实例从Session中移除时调用 |
- HttpSessionBindingEvent对象代表属性变化事件,它包含的方法如下:
方法名 | 作用 |
---|
getName() | 获取当前事件涉及的属性名 |
getValue() | 获取当前事件涉及的属性值 |
getSession() | 获取触发事件的HttpSession对象 |
测试代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| package com.atguigu.listeners;
import jakarta.servlet.http.HttpSession; import jakarta.servlet.http.HttpSessionBindingEvent; import jakarta.servlet.http.HttpSessionBindingListener;
public class MySessionBindingListener implements HttpSessionBindingListener { @Override public void valueBound(HttpSessionBindingEvent event) { HttpSession session = event.getSession(); String name = event.getName(); System.out.println("MySessionBindingListener"+this.hashCode()+" binding into session"+session.hashCode()+" with name "+name); }
@Override public void valueUnbound(HttpSessionBindingEvent event) { HttpSession session = event.getSession(); String name = event.getName(); System.out.println("MySessionBindingListener"+this.hashCode()+" unbond outof session"+session.hashCode()+" with name "+name); } }
|
1 2 3 4 5 6 7 8 9 10 11 12
| @WebServlet(urlPatterns = "/servletA",name = "servletAName") public class ServletA extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(); session.setAttribute("bindingListener",new MySessionBindingListener()); session.removeAttribute("bindingListener"); } }
|
2. 钝化活化监听器
HttpSessionActivationListener 监听某个对象在Session中的序列化与反序列化。
方法名 | 作用 |
---|
sessionWillPassivate(HttpSessionEvent se) | 该类实例和Session一起钝化到硬盘时调用 |
sessionDidActivate(HttpSessionEvent se) | 该类实例和Session一起活化到内存时调用 |
- HttpSessionEvent对象代表事件对象,通过getSession()方法获取事件涉及的HttpSession对象。
什么是钝化活化
- session对象在服务端是以对象的形式存储于内存的,session过多,服务器的内存也是吃不消的
- 而且一旦服务器发生重启,所有的session对象都将被清除,也就意味着session中存储的不同客户端的登录状态丢失
- 为了分摊内存 压力并且为了保证session重启不丢失,我们可以设置将session进行钝化处理
- 在关闭服务器前或者到达了设定时间时,对session进行序列化到磁盘,这种情况叫做session的钝化
- 在服务器启动后或者再次获取某个session时,将磁盘上的session进行反序列化到内存,这种情况叫做session的活化
如何配置钝化活化
1 2 3 4 5 6
| <?xml version="1.0" encoding="UTF-8"?> <Context> <Manager className="org.apache.catalina.session.PersistentManager" maxIdleSwap="1"> <Store className="org.apache.catalina.session.FileStore" directory="d:\mysession"></Store> </Manager> </Context>
|
- 请求servletA,获得session,并存入数据,然后重启服务器
1 2 3 4 5 6 7 8 9
| @WebServlet(urlPatterns = "/servletA",name = "servletAName") public class ServletA extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(); session.setAttribute("k1","v1"); } }
|
- 请求servletB获取session,获取重启前存入的数据
1 2 3 4 5 6 7 8 9 10
| @WebServlet(urlPatterns = "/servletB", name = "servletBName") public class ServletB extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(); Object v1 = session.getAttribute("k1"); System.out.println(v1);
} }
|
如何监听钝化活化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| package com.atguigu.listeners;
import jakarta.servlet.http.HttpSession; import jakarta.servlet.http.HttpSessionActivationListener; import jakarta.servlet.http.HttpSessionEvent;
import java.io.Serializable;
public class ActivationListener implements HttpSessionActivationListener, Serializable { @Override public void sessionWillPassivate(HttpSessionEvent se) { HttpSession session = se.getSession(); System.out.println("session with JSESSIONID "+ session.getId()+" will passivate"); }
@Override public void sessionDidActivate(HttpSessionEvent se) { HttpSession session = se.getSession(); System.out.println("session with JSESSIONID "+ session.getId()+" did activate"); } }
|
1 2 3 4 5 6 7 8 9 10 11
| @WebServlet(urlPatterns = "/servletA",name = "servletAName") public class ServletA extends HttpServlet { @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpSession session = req.getSession(); session.setAttribute("k1","v1"); session.setAttribute("activationListener",new ActivationListener()); } }
|
下午真的好困啊,但是这段时间又渐渐地平稳了下来,要是可以停留在这段时间就好了o.O