当前位置: 首页 > news >正文

Spring AOP @Before (前置通知): 在目标方法执行前做什么?

在这里插入图片描述

核心定义

@Before 是 Spring AOP 中的一种**通知(Advice)**类型。它的核心作用是:

在“连接点(Join Point)”,也就是目标方法被执行之前,执行一段特定的逻辑代码。

你可以把它想象成一个“门卫”。在有人(调用方)要进入一个重要的房间(目标方法)之前,门卫(@Before 通知)会先执行一系列检查或准备工作,比如核对身份、记录来访时间等。


@Before 通知能做什么?(主要应用场景)

前置通知非常适合执行一些“准备”或“预检”性质的任务,这些任务不影响目标方法的执行结果,但对整个流程至关重要。

  1. 日志记录 (Logging/Auditing)

    • 这是最经典的应用。在方法执行前,记录下谁、在什么时间、尝试调用哪个方法,并传入了什么参数。
    • 示例:“用户 admin 正在尝试执行 updateProduct 操作,参数为: Product{id=101, name='New Laptop'}”。
  2. 权限校验 (Authorization/Security Check)

    • 在执行敏感操作(如删除数据、修改金额)前,检查当前登录的用户是否拥有足够的权限。
    • 如果没有权限,可以直接在 @Before 通知里抛出一个异常(如 PermissionDeniedException),这样目标方法就根本不会被执行,从而保证了系统的安全。
  3. 参数校验 (Parameter Validation)

    • 虽然 JSR-303/JSR-380 (Bean Validation) 是更通用的方式,但对于一些复杂的、跨领域的业务校验,使用 AOP 也很方便。
    • 例如,检查传入的参数是否为 null,数值是否在有效范围内等。如果校验失败,同样可以抛出异常来中断操作。
  4. 数据准备 (Data Preparation)

    • 在方法执行前,可能需要准备一些上下文环境信息。
    • 例如,将某些信息设置到 ThreadLocal 中,以便目标方法或后续的逻辑可以方便地获取。
  5. 开启事务或设置事务属性(不推荐,但技术上可行)

    • 虽然 Spring 提供了更强大的 @Transactional 注解来管理事务,但理论上你也可以在 @Before 中手动开启一个事务。不过,这种方式不推荐。

@Before 的一个关键特点:无法阻止目标方法执行(除非抛异常)

@Before 通知本身没有“否决权”。一旦 @Before 的代码成功执行完毕(没有抛出任何异常),控制权会自动交还给 AOP 框架,然后目标方法会被继续执行

  • 唯一能阻止目标方法执行的方式:在 @Before 通知的代码中主动抛出一个异常。异常会中断当前的执行流程,使得目标方法没有机会被调用。

如果你需要更复杂的控制,比如:

  • 根据条件决定是否执行目标方法。
  • 修改传入目标方法的参数。
  • 修改目标方法的返回值。

那么你应该使用功能更强大的 @Around (环绕通知)


代码示例

让我们看一个具体的例子,实现一个简单的日志记录功能。

1. 添加 AOP 依赖 (Maven)

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 创建一个业务服务类 (目标对象)

package com.example.service;import org.springframework.stereotype.Service;@Service
public class UserService {public String findUserById(Long id) {System.out.println("--- 核心业务逻辑:正在根据 ID 查询用户... ---");if (id < 1) {throw new IllegalArgumentException("用户ID必须大于0");}return "User" + id;}
}

3. 创建一个切面 (Aspect) 并定义 @Before 通知

package com.example.aop;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import java.util.Arrays;@Aspect  // 声明这是一个切面类
@Component // 将其注册为 Spring Bean
public class LoggingAspect {// 1. 定义一个可重用的切点 (Pointcut)// 拦截 com.example.service 包下所有类的所有公共方法@Pointcut("execution(public * com.example.service.*.*(..))")public void serviceLayerPointcut() {}// 2. 定义前置通知,并引用上面的切点@Before("serviceLayerPointcut()")public void logBefore(JoinPoint joinPoint) { // JoinPoint 对象包含了目标方法的信息// 获取方法签名String methodName = joinPoint.getSignature().getName();// 获取方法参数Object[] args = joinPoint.getArgs();System.out.println("==================================================");System.out.printf("[AOP 前置通知]: 方法 [%s] 即将执行...%n", methodName);System.out.printf("[AOP 前置通知]: 参数为: %s%n", Arrays.toString(args));System.out.println("==================================================");}
}

4. 运行代码

当你调用 userService.findUserById(101L) 时,控制台的输出会是:

==================================================
[AOP 前置通知]: 方法 [findUserById] 即将执行...
[AOP 前置通知]: 参数为: [101]
==================================================
--- 核心业务逻辑:正在根据 ID 查询用户... ---

可以看到,logBefore 方法(前置通知)在 findUserById 方法(目标方法)之前被成功执行了。

总结

特性描述
执行时机在目标方法被调用之前执行。
核心用途日志记录、权限校验、参数校验、数据准备等预处理工作。
控制能力不能直接阻止目标方法执行,也不能修改参数或返回值。
如何中断流程只能通过抛出异常来间接阻止目标方法的执行。
关键参数可以注入 JoinPoint 对象,用以获取目标方法的签名、参数等元数据。

简而言之,@Before 是一个强大而简单的工具,用于在核心业务逻辑开始前“插入”一段通用的横切逻辑。

相关文章:

  • ChatGPT上瘾,大脑萎缩47%!?
  • Windows本地部署wordpress
  • 矩阵置零C++
  • Mac电脑-Office 2024 长期支持版(Excel、Word、PPT)
  • 《Go语言圣经》map
  • F接口基础.go
  • 基于Spring Boot的计算机考研交流系统的设计与实现
  • 微信小程序canvas实现抽奖动画
  • Arduino Nano 33 BLE Sense Rev 2开发板使用指南之【环境搭建 / 点灯】
  • 视频续播功能实现 - 断点续看从前端到 Spring Boot 后端
  • IDE深度集成+实时反馈:企业级软件测试方案Parasoft如何重塑汽车巨头的测试流程
  • MyBatis原理剖析(三)--加载配置文件
  • shared_ptr 源码解析
  • 安卓vscodeAI开发实例
  • 【MySQL基础】MySQL内置函数全面解析:提升你的数据库操作效率
  • GVim-vimrc 字体缩放与界面优化配置
  • 一拖广角云台(一种广角镜头与云台相结合的监控设备)实现了动态追踪和预警功能
  • 开源ChatBI :深入解密 Spring AI Alibaba 的中文NL2SQL智能引擎
  • 门锁开关;与我们生活中紧密联系!
  • 前端vue js 使用插件 spark-md5 计算文件MD5值并封装成Promise异步调用方法
  • 导购类网站建设多少钱/发布新闻最快的网站
  • 做视频网站 版权怎么解决/武汉谷歌seo
  • 新疆交通厅建设局网站/百度免费发布信息网站
  • 一个完整的个人网站/襄阳网站seo
  • 免费做网站有哪些家/今日军事新闻头条视频
  • 音乐做音基题网站/seo实战培训