SpringBoot中监听器、过滤器、拦截器和AOP详解
SpringBoot中监听器、过滤器、拦截器和AOP详解
在构建 Spring Boot 应用程序时,监听器(Listener)、过滤器(Filter)、拦截器(Interceptor)和面向切面编程(AOP)是四种常用的机制,它们各自有不同的用途和执行时机。本文将详细介绍这四种技术的执行时机和区别,并附上示例代码帮助理解。
1. 监听器(Listener)
定义与特点
- 定义:监听器用于监听特定事件的发生,并在这些事件发生时执行相应的逻辑。
- 特点:
- 事件驱动:监听器通过订阅特定的事件,在事件发生时执行预定的逻辑。
- 解耦:监听器将事件处理逻辑从业务逻辑中分离出来,提高了代码的模块化和可维护性。
- 灵活性:可以通过配置文件或注解的方式轻松地添加或移除监听器。
常见的监听器
- ServletContextListener:监听整个 Web 应用程序的启动和关闭。
- ServletRequestListener:监听每个 HTTP 请求的开始和结束。
- HttpSessionListener:监听会话的创建和销毁。
- SpringApplicationRunListener:监听 Spring Boot 应用程序的启动过程。
示例代码
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;@WebListener
public class MyContextListener implements ServletContextListener {@Overridepublic void contextInitialized(ServletContextEvent sce) {System.out.println("Application started");// 初始化操作,例如加载配置文件}@Overridepublic void contextDestroyed(ServletContextEvent sce) {System.out.println("Application stopped");// 清理操作,例如释放资源}
}
2. 过滤器(Filter)
定义与特点
- 定义:过滤器是 Java Servlet API 的一部分,用于在请求到达目标资源(如 Servlet 或 JSP 页面)之前或在响应从目标资源返回到客户端之后进行预处理或后处理。
- 特点:
- 生命周期管理:过滤器具有初始化(
init
)、过滤(doFilter
)和销毁(destroy
)的方法,这些方法分别在过滤器创建、每次请求处理和服务器关闭时调用。 - 执行顺序:过滤器的执行顺序是由部署描述符(如
web.xml
)或等效的 Java 配置类中定义的过滤器映射所决定的。 - 跨容器:过滤器可以在任何实现了 Servlet 规范的容器中工作,这意味着它们可以用于任何基于 Servlet 的 Web 应用程序,而不仅仅是 Spring Boot 应用。
- 生命周期管理:过滤器具有初始化(
使用场景
- 安全性:实现身份验证和授权逻辑,确保只有经过验证的用户才能访问某些资源。
- 编码转换:在请求和响应中进行字符集转换,以支持国际化。
- 日志记录:记录每个请求的信息,用于调试和监控应用程序行为。
- 性能监控:测量请求处理时间,以便进行性能分析和优化。
- 资源限制:限制请求频率,防止资源滥用,例如通过实现速率限制功能。
- 响应头添加:自动添加 HTTP 响应头,如 CORS 支持或安全相关的头部信息。
示例代码
import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import java.io.IOException;@WebFilter(urlPatterns = "/*")
public class MyFilter implements Filter {@Overridepublic void init(FilterConfig filterConfig) throws ServletException {System.out.println("Filter initialized");// 初始化操作}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {System.out.println("Request received at filter");// 在请求处理之前进行预处理chain.doFilter(request, response);System.out.println("Response leaving filter");// 在响应发送之前进行后处理}@Overridepublic void destroy() {System.out.println("Filter destroyed");// 销毁操作}
}
3. 拦截器(Interceptor)
定义与特点
- 定义:拦截器是 Spring 框架中的一部分,主要用于在 Web 应用的 MVC 框架中拦截请求和响应,并在控制器方法调用前后以及请求处理完成后执行自定义的逻辑。
- 特点:
- 生命周期钩子:拦截器提供了多个钩子方法,如
preHandle
、postHandle
和afterCompletion
,分别在请求处理的开始、结束和完成后调用。 - 动态性:可以通过配置来决定哪些请求会被拦截器处理,而无需修改具体的控制器代码。
- 非侵入性:拦截器的设计使得业务逻辑与横切关注点分离,使得代码更加模块化和可维护。
- 可插拔性:可以根据需要轻松地添加、移除或更改拦截器,而不会影响到现有的业务逻辑。
- 生命周期钩子:拦截器提供了多个钩子方法,如
使用场景
- 权限认证与授权:在请求到达控制器之前检查用户的身份和权限,以确定是否允许访问相应的资源。
- 日志记录:记录请求和响应的信息,用于调试和监控应用程序行为。
- 请求参数修改:在请求到达控制器之前修改请求参数。
- 响应结果修改:在响应发送之前修改响应结果。
示例代码
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;@Component
public class MyInterceptor implements HandlerInterceptor {@Overridepublic boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {System.out.println("Request received at interceptor preHandle");// 在请求处理之前进行预处理return true; // 返回 true 表示放行,false 表示拦截}@Overridepublic void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {System.out.println("Request handled at interceptor postHandle");// 在请求处理之后,但在视图渲染之前进行处理}@Overridepublic void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {System.out.println("Response sent at interceptor afterCompletion");// 在请求处理完成之后进行处理}
}
注册拦截器
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;@Configuration
public class WebConfig implements WebMvcConfigurer {@Autowiredprivate MyInterceptor myInterceptor;@Overridepublic void addInterceptors(InterceptorRegistry registry) {registry.addInterceptor(myInterceptor).addPathPatterns("/**") // 拦截所有请求.excludePathPatterns("/login", "/logout"); // 排除登录和登出请求}
}
4. 面向切面编程(AOP)
定义与特点
- 定义:AOP 是一种编程范式,它允许你在不修改源代码的情况下,对程序的特定部分添加额外的功能。
- 特点:
- 横切关注点:AOP 将横切关注点(如日志记录、事务管理等)从业务逻辑中分离出来,使得代码更加模块化和可维护。
- 动态代理:Spring AOP 通过动态代理机制实现,可以在运行时织入切面(Aspect)到目标对象中。
- 灵活的通知类型:Spring AOP 提供了多种通知类型,如
@Before
、@After
、@Around
、@AfterReturning
和@AfterThrowing
,分别在方法执行前、后、环绕、返回后和抛出异常时执行。
使用场景
- 事务管理:在方法执行前后管理事务的开启、提交和回滚。
- 日志记录:记录方法的调用信息,用于调试和监控应用程序行为。
- 性能监控:测量方法的执行时间,以便进行性能分析和优化。
- 安全控制:在方法调用前检查用户的权限,以确保安全。
示例代码
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;@Aspect
@Component
public class LoggingAspect {@Before("execution(* com.example.demo.controller.*.*(..))")public void logBefore(JoinPoint joinPoint) {System.out.println("Before method: " + joinPoint.getSignature().getName());// 在方法执行前记录日志}@After("execution(* com.example.demo.controller.*.*(..))")public void logAfter(JoinPoint joinPoint) {System.out.println("After method: " + joinPoint.getSignature().getName());// 在方法执行后记录日志}
}
总结
- 监听器(Listener):用于监听特定事件的发生,并在这些事件发生时执行相应的逻辑。适用于应用程序的生命周期管理和事件驱动的场景。
- 过滤器(Filter):用于在请求到达目标资源之前或在响应从目标资源返回到客户端之后进行预处理或后处理。适用于安全性、编码转换、日志记录等场景。
- 拦截器(Interceptor):用于在 Web 应用的 MVC 框架中拦截请求和响应,并在控制器方法调用前后以及请求处理完成后执行自定义的逻辑。适用于权限认证、日志记录、请求参数修改等场景。
- 面向切面编程(AOP):用于在不修改源代码的情况下,对程序的特定部分添加额外的功能。适用于事务管理、日志记录、性能监控等场景。
通过本文的介绍和示例代码,希望读者能够更好地理解和使用这些机制,提高 Spring Boot 应用程序的开发效率和代码质量。
相关文章:
SpringBoot中监听器、过滤器、拦截器和AOP详解
SpringBoot中监听器、过滤器、拦截器和AOP详解 在构建 Spring Boot 应用程序时,监听器(Listener)、过滤器(Filter)、拦截器(Interceptor)和面向切面编程(AOP)是四种常用…...

如何让手机ip变成动态
在数字化浪潮中,手机已成为我们日常生活中不可或缺的一部分。无论是浏览网页、使用社交媒体还是进行在线购物,手机都扮演着举足轻重的角色。然而,在享受网络带来的便利时,我们也需要关注网络安全和隐私保护。静态IP地址可能让手机…...

[Qt platform plugin问题] Could not load the Qt platform plugin “xcb“
Qt platform plugin 是 Qt 应用程序启动时加载的插件。不同的平台有不同的插件。 常见的插件有:linuxfb Wayland xcb 简单来说就是启动一个GUI程序, 离不开这些插件.选择其中一个就好 出现这个问题要么就是没有插件,要么就是插件依赖的库没有。 要么就是插件选则的…...
嵌入式开发人员如何选择合适的开源前端框架进行Web开发
在嵌入式系统的Web开发中,前端框架的选择对于项目的成败有着决定性的影响。一个合适的框架不仅能提高开发效率,还能保证系统的稳定性和可扩展性。本文将介绍几款适用于嵌入式Web开发的开源前端框架,并探讨它们的优缺点。 1. Element Plus V…...
MySQL数据库(七)----查询相关操作(子查询)
子查询是指在一个查询语句(主查询)内部嵌套的另一个查询语句。子查询可以出现在 SELECT、FROM、WHERE、HAVING 等子句中。它可以将一个复杂的查询问题分解为多个简单的查询步骤,从而更方便地获取所需的数据。 引入子查询: -- 查…...

01_Spring开胃菜
一、 为什么是Spring? 在正式进入Spring内容前我们先看看我们以往经典的程序设计。 当我们去登录时,会调用后端的Controller,Controller接收到用户的请求后会调用业务层的Service进行登录的业务处理,Service业务处理过程中会调用Dao层向DB获取数进行判断。 接下来我们用代…...
SpringBoot使用AspectJ的@Around注解实现AOP全局记录接口:请求日志、响应日志、异常日志
Spring 面向切面编程(AOP),系列文章: 《Spring面向切面编程(AOP)的简单实例》 《Spring使用AspectJ的注解式实现AOP面向切面编程》 《SpringBoot使用AspectJ实现AOP记录接口:请求日志、响应日志、异常日志》 《SpringBoot使用AspectJ的@Around注解实现AOP全局记录接口:…...
WPF下播放Rtmp的解决方案
介绍 在实际的开发过程中,需要在应用内部内嵌播放器进行视频的播放。官方默认的MediaElement控件只能播放有限的视频格式,也不能播放网络流。比较流行的解决方式是vlc的库,但是在实际使用过程中发现有很多问题。这里给大家推荐另一个比较好的…...

7.高可用集群架构Keepalived双主热备原理
一. 高可用集群架构Keepalived双主热备原理 (1)主机+备机keepalived配置(192.168.1.171) ! Configuration File for keepalivedglobal_defs {# 路由id:当前安装keepalived节点主机的标识符,全局唯一router_id keep_101 } #计算机节点(主机配置) vrrp_instance VI_1 {</...

为以人工智能为中心的工作负载重新设计的全局控制台
MinIO 控制台多年来一直是一个不断发展的产品。每次学习时,我们都会思考如何改进交互框架中这个非常重要的部分。首先是控制台,它在推出后的一年内就被广泛采用。更具体地说,超过 10K 个组织。接下来是企业控制台。这从对象存储与其 GUI 之间…...
go channel中的 close注意事项 range取数据
在使用 Go 语言中的 close 函数时,有一些注意事项需要牢记,以确保程序的健壮性和正确性: 1. **仅用于通道(channel)**: - close 函数只能用于关闭通道,不能用于关闭文件、网络连接或其他资源…...

Vue3 -- 项目配置之eslint【企业级项目配置保姆级教程1】
下面是项目级完整配置1➡eslint:【吐血分享,博主踩过的坑你跳过去!!跳不过去?太过分了给博主打钱】 浏览器自动打开项目: 你想释放双手吗?你想每天早上打开电脑运行完项目自动在浏览器打开吗&a…...

鸿蒙开发应用权限管理
简介 一种允许应用访问系统资源(如:通讯录等)和系统能力(如:访问摄像头、麦克风等)的通用权限访问方式,来保护系统数据(包括用户个人数据)或功能,避免它们被…...

【数据库】如何保证数据库迁移过程中数据的一致性?
在数据库迁移过程中,保证数据的一致性是非常重要的,尤其是在涉及到多个表、多个数据库或分布式系统的情况下。以下是一些确保数据一致性的最佳实践和方法: 1. 备份数据 在开始迁移之前,进行全面的数据备份是确保数据一致性的第…...

C++之内存管理
🌹个人主页🌹:喜欢草莓熊的bear 🌹专栏🌹:C入门 目录 前言 一、C/C内存分配 二、 malloc、calloc、realloc、free 三、C内存管理方式 3.1 new/delete 操作内置类型 3.2 new和detele操作自定义类型…...
ISP是什么?
isp全称为Internet Service Provider,即互联网服务提供商,是一种向用户提供互联网接入服务的公司或组织,它们提供的服务包括互联网接入、域名注册、网站托管等等。 ISP的应用场景非常广泛,几乎所有的互联网用户都需要通过ISP来接…...

机房动环境监控用各种列表已经淘汰了,现在都是可视化图表展示了
在信息技术飞速发展的今天,机房作为数据存储、处理和传输的核心场所,其稳定运行至关重要。过去,机房动环境监控主要依赖各种列表形式来呈现数据,但如今,这种方式已经逐渐被淘汰,取而代之的是更加直观、高效…...

RHCE的练习(12)
写一个脚本,完成以下要求: 给定一个用户: 如果其UID为0,就显示此为管理员;否则,就显示其为普通用户; #!/bin/bash # 使用read命令获取用户名 read -p "请输入用户名: " username …...

uniapp自动注册机制:easycom
传统 Vue 项目中,我们需要注册、导入组件之后才能使用组件。 uniapp 框架提供了一种组件自动注册机制,只要你在 components 文件夹下新建的组件满足 /components/组件名/组件名.vue 的命名规范,就能直接使用。 注意:组件的文件夹…...
【论文阅读】(Security) Assertions by Large Language Models
论文笔记:(Security) Assertions by Large Language Models 来源:IEEE TRANSACTIONS ON INFORMATION FORENSICS AND SECURITY I. 引言 计算机系统的安全性通常依赖于硬件的根信任。硬件漏洞可能对系统造成严重影响,因此需要支持安全验证的技术。断言验证是一种流行的验证…...
SciencePlots——绘制论文中的图片
文章目录 安装一、风格二、1 资源 安装 # 安装最新版 pip install githttps://github.com/garrettj403/SciencePlots.git# 安装稳定版 pip install SciencePlots一、风格 简单好用的深度学习论文绘图专用工具包–Science Plot 二、 1 资源 论文绘图神器来了:一行…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具
作者:来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗?了解下一期 Elasticsearch Engineer 培训的时间吧! Elasticsearch 拥有众多新功能,助你为自己…...
IGP(Interior Gateway Protocol,内部网关协议)
IGP(Interior Gateway Protocol,内部网关协议) 是一种用于在一个自治系统(AS)内部传递路由信息的路由协议,主要用于在一个组织或机构的内部网络中决定数据包的最佳路径。与用于自治系统之间通信的 EGP&…...

【网络安全产品大调研系列】2. 体验漏洞扫描
前言 2023 年漏洞扫描服务市场规模预计为 3.06(十亿美元)。漏洞扫描服务市场行业预计将从 2024 年的 3.48(十亿美元)增长到 2032 年的 9.54(十亿美元)。预测期内漏洞扫描服务市场 CAGR(增长率&…...

论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
相机Camera日志分析之三十一:高通Camx HAL十种流程基础分析关键字汇总(后续持续更新中)
【关注我,后续持续新增专题博文,谢谢!!!】 上一篇我们讲了:有对最普通的场景进行各个日志注释讲解,但相机场景太多,日志差异也巨大。后面将展示各种场景下的日志。 通过notepad++打开场景下的日志,通过下列分类关键字搜索,即可清晰的分析不同场景的相机运行流程差异…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...

Mac下Android Studio扫描根目录卡死问题记录
环境信息 操作系统: macOS 15.5 (Apple M2芯片)Android Studio版本: Meerkat Feature Drop | 2024.3.2 Patch 1 (Build #AI-243.26053.27.2432.13536105, 2025年5月22日构建) 问题现象 在项目开发过程中,提示一个依赖外部头文件的cpp源文件需要同步,点…...
Go 并发编程基础:通道(Channel)的使用
在 Go 中,Channel 是 Goroutine 之间通信的核心机制。它提供了一个线程安全的通信方式,用于在多个 Goroutine 之间传递数据,从而实现高效的并发编程。 本章将介绍 Channel 的基本概念、用法、缓冲、关闭机制以及 select 的使用。 一、Channel…...