Spring Boot监听器的用法(非常详细)
Web 监听器是 Servlet 中特殊的类,能帮助开发者监听 Web 中的一些特定事件,比如 ServletContext、HttpSession、ServletRequest 的创建和销毁,在某些动作前后增加处理,以及实现监控等。
按照监听对象,Web 监听器可分为三类:
Web 监听器的使用场景很多,比如监听 Servlet 上下文来初始化一些数据,监听 Session 会话获取当前系统在线人数,监听客户端请求的 ServletRequest 来获取用户的一些访问信息。
接下来我们将通过实际例子和实际场景讲解这三类监听器以及自定义监听器。
页面上使用数据的时候直接从 application 作用域获取,而不是每次获取数据都要从数据库中获取。如果用户量大,那么每次首页菜单加载对于数据库来说都是很大的一笔开销。
下面将针对首页展示用户账号信息这个场景,来对 ServletContext 监听器做实际讲解。
1) 模拟数据库查询用户信息,参考代码如下:
2) 定义一个监听 ServletContext 的监听器,需要实现 ServletContextListener 接口,并且重写 onApplicationEvent 方法,参考代码如下:
3) 创建一个接口,从 application 作用域中获取初始化的 User 信息,返回到页面中,参考代码如下:
接口请求结果如下图所示:
1) 创建 Session 会话监听器,需要实现 HttpSessionListener 接口,并且按照自身需求重写 sessionCreated() 方法和 sessionDestroyed() 方法,参考代码如下:
2) 创建一个接口测试该监听器,参考代码如下:
1) 创建监听 ServletRequest 对象的监听器,需要实现 ServletRequestListener 接口,按照自身需求重写 requestInitialized() 方法和 requestDestroyed() 方法,参考代码如下:
2) 新增一个接口,测试 ServletRequest 对象的监听器,参考代码如下:

自定义监听器
实现自定义监听器需要做三步操作:
1) 自定义事件,参考代码如下:
2) 自定义监听器,参考代码如下:
3) 发布事件,参考代码如下:
4) 创建接口测试自定义监听器,参考代码如下:
按照监听对象,Web 监听器可分为三类:
- Servlet 上下文监听器 ApplicationListener;
- Session 对象的监听器 HttpSessionListener;
- Request 对象的监听器 ServletRequestListener。
Web 监听器的使用场景很多,比如监听 Servlet 上下文来初始化一些数据,监听 Session 会话获取当前系统在线人数,监听客户端请求的 ServletRequest 来获取用户的一些访问信息。
接下来我们将通过实际例子和实际场景讲解这三类监听器以及自定义监听器。
监听ServletContext对象
监听 ServletContext 对象主要用于初始化一些不经常改变的数据,比如网站首页的一些菜单信息、用户账号相关信息等,将这些数据存进 application 作用域中,在一定程度上会起到缓存的作用。页面上使用数据的时候直接从 application 作用域获取,而不是每次获取数据都要从数据库中获取。如果用户量大,那么每次首页菜单加载对于数据库来说都是很大的一笔开销。
下面将针对首页展示用户账号信息这个场景,来对 ServletContext 监听器做实际讲解。
1) 模拟数据库查询用户信息,参考代码如下:
@Service public class UserServiceImpl implements UserService { @Override public User getUser() { return new User(111L, "tudoudou", "aaa"); } }
2) 定义一个监听 ServletContext 的监听器,需要实现 ServletContextListener 接口,并且重写 onApplicationEvent 方法,参考代码如下:
/** * Servlet上下文监听器 */ @Component public class ServletContextListener implements ApplicationListener<ContextRefreshedEvent> { @Override public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent) { // 获取 application 上下文信息 ApplicationContext applicationContext = contextRefreshedEvent.getApplicationContext(); // 获取 userService 对象 UserServiceImpl userServiceImpl = applicationContext.getBean(UserServiceImpl.class); User user = userServiceImpl.getUser(); // 将获取的 user 对象放入 application 域中 ServletContext applicationScope = applicationContext.getBean(ServletContext.class); applicationScope.setAttribute("user", user); } }
3) 创建一个接口,从 application 作用域中获取初始化的 User 信息,返回到页面中,参考代码如下:
@GetMapping("/user") public User getUser(HttpServletRequest request){ ServletContext applicationScope = request.getServletContext(); User user = (User)applicationScope.getAttribute("user"); return user; }
接口请求结果如下图所示:

监听HTTP会话Session对象
Web 监听器还有一个比较常用的作用就是监听 Session 对象,以统计当前Web应用在线用户总数量。下面将通过统计在线用户数量来具体讲解 Session 会话监听器。1) 创建 Session 会话监听器,需要实现 HttpSessionListener 接口,并且按照自身需求重写 sessionCreated() 方法和 sessionDestroyed() 方法,参考代码如下:
/** * httpSession 监听对象 */ @Component public class SessionListener implements HttpSessionListener { // 用于记录在线用户数量 public static Integer count = 0; @Override public void sessionCreated(HttpSessionEvent se) { System.out.println("新用户上线!"); count++; se.getSession().getServletContext().setAttribute("count", count); } @Override public void sessionDestroyed(HttpSessionEvent se) { System.out.println("用户下线!"); count--; se.getSession().getServletContext().setAttribute("count", count); } }
2) 创建一个接口测试该监听器,参考代码如下:
@GetMapping("/countOnlineUser") public String getOnlineUserCount(HttpServletRequest request, HttpServletResponse response) { Cookie cookie; try { // 将 sessionId 记录到浏览器中,防止在服务器找不到原有的用户信息,重新创建 session cookie = new Cookie("JSESSIONID", URLEncoder.encode(request.getSession().getId(), "utf-8")); cookie.setPath("/"); // 设置 cookie 有效期为 1 天 cookie.setMaxAge(24 * 60 * 60); response.addCookie(cookie); } catch (Exception e) { e.printStackTrace(); } Integer count = (Integer) request.getSession().getServletContext().getAttribute("count"); return "total user online:" + count; }测试结果如下图所示:

监听ServletRequest对象
监听客户端请求,主要是为了获取用户的一些请求信息,具体操作如下。1) 创建监听 ServletRequest 对象的监听器,需要实现 ServletRequestListener 接口,按照自身需求重写 requestInitialized() 方法和 requestDestroyed() 方法,参考代码如下:
/** * request 请求 listener,获取请求访问信息 */ @Component public class RequestListener implements ServletRequestListener { @Override public void requestInitialized(ServletRequestEvent sre) { System.out.println("此次请求开始"); HttpServletRequest request = (HttpServletRequest) sre.getServletRequest(); System.out.println("sessionId:" + request.getRequestedSessionId() + " url:" + request.getRequestURL()); String username = (String) request.getAttribute("username"); if (username == null) { request.setAttribute("username", "tudoudou"); } } @Override public void requestDestroyed(ServletRequestEvent sre) { System.out.println("此次请求结束"); HttpServletRequest request = (HttpServletRequest) sre.getServletRequest(); String username = (String) request.getAttribute("username"); System.out.println("requestScope 中 username 为:" + username); } }
2) 新增一个接口,测试 ServletRequest 对象的监听器,参考代码如下:
@GetMapping("/testRequest") public String testRequest(HttpServletRequest request){ String username = (String)request.getAttribute("username"); System.out.println("init requestScope username:"+username); return "success"; }测试结果如下图所示:

自定义监听器
实现自定义监听器需要做三步操作:
- 首先,自定义事件,即监听器用来监听的事件,该事件需要继承 ApplicationEvent 对象;
- 其次,自定义一个监听器加监听自定义的时间,该监听器需要实现 ApplicationListener 接口;
- 最后,手动发布事件,发布之后监听器才能监听到,当然,发布事件可以根据实际业务场景进行操作。
1) 自定义事件,参考代码如下:
/** * 自定义监听事件 */ public class MyEvent extends ApplicationEvent { private User user; public MyEvent(Object source, User user) { super(source); this.user = user; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
2) 自定义监听器,参考代码如下:
/** * 自定义监听器 */ @Component public class MyEventListener implements ApplicationListener<MyEvent> { @Override public void onApplicationEvent(MyEvent myEvent) { // 获取事件中的信息 User user = myEvent.getUser(); // 打印获取到的信息 System.out.println("username:" + user.getUsername()); } }
3) 发布事件,参考代码如下:
/** * User 用户 service 接口类实现类 */ @Service public class UserServiceImpl implements UserService { @Autowired private ApplicationContext applicationContext; @Override public User publishMyEvent() { User user = new User(100L, "doudou", "111"); // 发布自定义事件 MyEvent myEvent = new MyEvent(this, user); applicationContext.publishEvent(myEvent); return user; } }
4) 创建接口测试自定义监听器,参考代码如下:
@GetMapping("/publish") public User publishMyEvent(HttpServletRequest request) { return userService.publishMyEvent(); }