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 框架中拦截请求和响应,并在控制器方法调用前后以及请求处理完成后执行自定义的逻辑。
  • 特点
    • 生命周期钩子:拦截器提供了多个钩子方法,如 preHandlepostHandleafterCompletion,分别在请求处理的开始、结束和完成后调用。
    • 动态性:可以通过配置来决定哪些请求会被拦截器处理,而无需修改具体的控制器代码。
    • 非侵入性:拦截器的设计使得业务逻辑与横切关注点分离,使得代码更加模块化和可维护。
    • 可插拔性:可以根据需要轻松地添加、移除或更改拦截器,而不会影响到现有的业务逻辑。
使用场景
  • 权限认证与授权:在请求到达控制器之前检查用户的身份和权限,以确定是否允许访问相应的资源。
  • 日志记录:记录请求和响应的信息,用于调试和监控应用程序行为。
  • 请求参数修改:在请求到达控制器之前修改请求参数。
  • 响应结果修改:在响应发送之前修改响应结果。
示例代码
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 应用程序的开发效率和代码质量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/18530.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

第二十周:机器学习

目录 摘要 ABSTRACT 一、吴恩达机器学习exp2——逻辑回归 1、logistic函数 2、数据预处理 3、损失函数 4、梯度下降 5、设定评价指标 6、决策边界 7、正则化 二、动手深度学习pytorch——数据预处理 1、数据集读取 2、缺失值处理 3、转换为张量格式 总结 摘要…

从人-物到人-机再到人-AI

从 人-物 到 人-机 再到 人-AI ,这一演化过程展现了人类与技术、工具的互动方式随着时代的发展而发生的深刻变化。这一变化不仅是技术进步的体现,更是社会、文化以及工作方式的根本转变。以下是这一演变的主要特点及其背后的影响: 1. 人-物时…

go-zero(三) 数据库操作

go-zero 数据库操作 在本篇文章中,我们将实现一个用户注册和登录的服务。我们将为此构建一个简单而高效的 API,包括请求参数和响应参数的定义。 一、Mysql连接 1. 创建数据库和表 在 MySQL 中创建名为 test_zero的数据库,并创建user 表 …

【ASR技术】WhisperX安装使用

介绍 WhisperX 是一个开源的自动语音识别(ASR)项目,由 m-bain 开发。该项目基于 OpenAI 的 Whisper 模型,通过引入批量推理、强制音素对齐和语音活动检测等技术。提供快速自动语音识别(large-v2 为 70 倍实时&#xf…

【C++ 算法进阶】算法提升十六

目录 背包问题变种 (动态规划)题目题目分析 连续可组成数字题目题目分析 min-patches题目 最小补丁问题题目分析代码 逆序对个数 (归并排序)题目题目分析 约瑟夫环问题 (公式)题目题目分析 背包问题变种 &a…

链表的基本操作

链表,由若干个结点组成,每个结点包含数据域和指针域。结点结构如下图所示: 一般来讲,链表中只会有一个结点的指针域为空,该结点为尾结点,其他结点的指针域都会存储一个结点的内存地址。链表中也只会有一个结…

C#高级:Winform中的自定义窗体输入

目录 一、多样式输入(无封装) 1.代码 2.效果 二、单输入框封装 1.使用 2.封装 3.效果 三、组合框批量输入封装 1.使用 2.封装 3.效果 一、多样式输入(无封装) 1.代码 private async void button1_Click(object send…

memblock内存分配器

一、简述 memblock 是 Linux 内核中的一个内存管理子系统,主要用于在系统启动早期阶段管理物理内存。它在内核初始化期间负责管理内存,直到更复杂的内存管理子系统(如伙伴系统)接管。 二、工作原理 初始化:在内核启…

【C++滑动窗口】1248. 统计「优美子数组」|1623

本文涉及的基础知识点 C算法:滑动窗口及双指针总结 LeetCode1248. 统计「优美子数组」 给你一个整数数组 nums 和一个整数 k。如果某个连续子数组中恰好有 k 个奇数数字,我们就认为这个子数组是「优美子数组」。 请返回这个数组中 「优美子数组」 的数…

⽂件内容的读写

文件 InputStream (字节流读出 抽象类) InputStream 只是⼀个抽象类,要使⽤还需要具体的实现类 FileInputStream(字节流读出) OutputStream(字节流写入) Reader(字符流读入&#xff…

FreeRTOS消息队列实验与出现的问题

目录 实验名字:队列操作实验 1、实验目的 2、实验设计 3、实验工程 4、实验程序与分析 ●任务设置 ● 其他应用函数 ● main()函数 ● 任务函数 ●中断初始化及处理过程 5.程序运行结果分析 6.进行实验移植时所遇到的问题 1.项目中mymalloc等函数缺少 …

el-cascader 使用笔记

1.效果 2.官网 https://element.eleme.cn/#/zh-CN/component/cascader 3.动态加载&#xff08;官网&#xff09; <el-cascader :props"props"></el-cascader><script>let id 0;export default {data() {return {props: {lazy: true,lazyLoad (…

Linux之进程概念(2)

Linux之进程概念&#xff08;2&#xff09; 孤儿进程 父进程如果提前退出&#xff0c;那么子进程后退出&#xff0c;进入Z之后&#xff0c;那该如何处理呢&#xff1f; 父进程先退出&#xff0c;子进程就称之为“孤儿进程” 孤儿进程被1号init进程领养&#xff0c;当然要有in…

1+X应急响应(网络)日志分析:

日志分析&#xff1a; Web日志分析&#xff1a; http协议&#xff1a; http版本演变&#xff1a; http协议工作原理&#xff1a; http协议的特点&#xff1a; http请求报文&#xff1a; http请求方法&#xff1a; http响应报文&#xff1a; UserId&#xff1a;注册网站的序列号…

go-zero(二) api语法和goctl应用

go-zero api语法和goctl应用 在实际开发中&#xff0c;我们更倾向于使用 goctl 来快速生成代码。 goctl 可以根据 api快速生成代码模板&#xff0c;包括模型、逻辑、处理器、路由等&#xff0c;大幅提高开发效率。 一、构建api demo 现在我们通过 goctl 创建一个最小化的 HT…

计算机编程中的设计模式及其在简化复杂系统设计中的应用

&#x1f493; 博客主页&#xff1a;瑕疵的CSDN主页 &#x1f4dd; Gitee主页&#xff1a;瑕疵的gitee主页 ⏩ 文章专栏&#xff1a;《热点资讯》 计算机编程中的设计模式及其在简化复杂系统设计中的应用 计算机编程中的设计模式及其在简化复杂系统设计中的应用 计算机编程中的…

latex中,两个相邻的表格,怎样留一定的空白

目录 问题描述 问题解决 问题描述 在使用latex写论文时&#xff0c;经常表格需要置顶写&#xff0c;则会出现两个表格连在一起的情况。下一个表名容易与上面的横线相连&#xff0c;如何通过明令&#xff0c;留出一定的空白。 问题解决 在第二个表格的 \centering命令之后…

leetcode01——合并两个有序数组

0.本题学到的知识 1.python的操作中&#xff0c;哪些是在原数据上进行操作的&#xff1f; 新开辟的行为&#xff1a;list1list1[m:n] 原数据&#xff1a;list1[a:b]list1[m:n] 新开辟&#xff1a;list1list1list2 原数据&#xff1a;list1.append(list2[i]); list1.extend(list…

深度学习的艺术:揭秘卷积神经网络(CNN)的神秘面纱

深度学习的艺术&#xff1a;揭秘卷积神经网络&#xff08;CNN&#xff09;的神秘面纱 一、CNN的构成要素二、CNN的工作流程三、CNN的应用领域四、CNN的优势与局限 #引言&#xff1a; 在人工智能的璀璨星空中&#xff0c;卷积神经网络&#xff08;CNN&#xff09;如同一颗耀眼的…

Linux高阶——1116—环形队列生产者消费者

目录 1、环形队列 2、生产者消费者 环形队列数组实现代码 成功截图 1、环形队列 相比于线性队列&#xff0c;环形队列可以有效避免访问越界问题&#xff0c;使用下标访问队列元素时&#xff0c;到达末尾后下标归0&#xff0c;返回起始位置&#xff0c;使用下标运算即可 a…