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

二(8.4)注解和aop

1. AOP 是 Aspect-Oriented Programming,面向切面编程。

它常常和 Java 注解一起使用,尤其在 Spring 里非常常见。可以简单理解为:
注解负责“标记哪里需要增强”,AOP 负责“在这些地方自动插入增强逻辑”。

比如:

@LogExecutionTimepublicvoidcreateOrder(){// 创建订单}

这个方法本身只关心“创建订单”,而 @LogExecutionTime 表示:这个方法需要记录执行时间。真正记录时间的逻辑,可以交给 AOP 自动处理。

2. AOP 是什么?

AOP 的核心思想是:把一些和业务无关、但很多地方都需要的通用逻辑抽出来,统一处理。
常见场景包括:

日志记录 权限校验 事务管理 接口限流 性能监控 异常处理 缓存处理 审计记录

比如一个订单服务:

publicvoidcreateOrder(){checkPermission();startTransaction();// 真正的业务逻辑saveOrder();commitTransaction();log();}

如果每个方法都这样写,业务代码会变得很乱。
AOP 的作用就是让业务方法保持干净:

publicvoidcreateOrder(){saveOrder();}

而权限、事务、日志这些逻辑由 AOP 在方法执行前后自动加进去。

3. AOP 的几个核心概念

3.1. 切面 Aspect

切面就是一组横切逻辑的集合。
比如“日志切面”“权限切面”“事务切面”。

@Aspect@ComponentpublicclassLogAspect{}

3.2. 连接点 Join Point

连接点是程序执行过程中的某个点。
在 Spring AOP 里,通常指的是“方法调用”。
比如:

userService.createUser()orderService.createOrder()

这些方法执行点都可以被 AOP 拦截。

3.3. 切点 Pointcut

切点用来指定:哪些方法需要被拦截。
比如拦截所有 service 包下的方法:

@Pointcut("execution(* com.example.service.*.*(..))")publicvoidserviceMethods(){}

也可以拦截带有某个注解的方法:

@Pointcut("@annotation(com.example.annotation.LogExecutionTime)")publicvoidlogExecutionTimeMethods(){}

3.4. 通知 Advice

通知就是“什么时候执行增强逻辑”。
常见通知类型:

@Before方法执行前@After方法执行后,不管是否异常@AfterReturning方法正常返回后@AfterThrowing方法抛异常后@Around包围方法执行,最强大

例如:

@Before("serviceMethods()")publicvoidbefore(){System.out.println("方法执行前");}

2. 注解和 AOP 如何配合?

通常分三步。

第一步:定义一个注解

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public@interfaceLogExecutionTime{}

解释一下:

@Target(ElementType.METHOD)

表示这个注解只能加在方法上。

@Retention(RetentionPolicy.RUNTIME)

表示这个注解在运行时仍然保留,这样 AOP 才能在运行时识别它。

第二步:在业务方法上使用注解

@ServicepublicclassOrderService{@LogExecutionTimepublicvoidcreateOrder(){System.out.println("创建订单");}}

这时 createOrder() 被标记为“需要记录执行时间”。

第三步:用 AOP 拦截这个注解

@Aspect@ComponentpublicclassLogAspect{@Around("@annotation(com.example.annotation.LogExecutionTime)")publicObjectlogExecutionTime(ProceedingJoinPointjoinPoint)throwsThrowable{longstart=System.currentTimeMillis();Objectresult=joinPoint.proceed();longend=System.currentTimeMillis();System.out.println(joinPoint.getSignature().getName()+" 执行耗时:"+(end-start)+"ms");returnresult;}}

核心是这一句:

@Around("@annotation(com.example.annotation.LogExecutionTime)")

意思是:拦截所有加了 @LogExecutionTime 注解的方法。
而这一句:

joinPoint.proceed();

表示执行原来的业务方法。
所以执行流程大概是:

调用createOrder()↓ 进入AOP切面 ↓ 记录开始时间 ↓ 执行createOrder()原始方法 ↓ 记录结束时间 ↓ 打印耗时 ↓ 返回结果

3. 一个更实际的例子:权限校验

定义注解:

@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)public@interfaceRequireRole{Stringvalue();}

使用注解:

@RequireRole("admin")publicvoiddeleteUser(LonguserId){// 删除用户}

AOP 拦截:

@Around("@annotation(requireRole)")publicObjectcheckRole(ProceedingJoinPointjoinPoint,RequireRolerequireRole)throwsThrowable{StringrequiredRole=requireRole.value();// 假设这里拿到当前用户角色StringcurrentRole="user";if(!requiredRole.equals(currentRole)){thrownewRuntimeException("权限不足");}returnjoinPoint.proceed();}

这样业务代码只需要写:

@RequireRole("admin")

不用在每个方法里手动写权限判断。

4. 为什么注解适合配合 AOP?

因为注解本身不做事情,它只是一个“标记”或“配置”。
比如:

@RequireRole("admin")

它只是告诉系统:这个方法需要 admin 权限。

但真正的权限判断逻辑,需要 AOP 去执行。
所以它们的关系可以理解为:

注解:声明意图AOP:执行逻辑
http://www.jsqmd.com/news/1134673/

相关文章:

  • ctf竞赛解题1
  • Windows 11 微软账号登录卡顿:3种DNS方案实测与网络服务排查指南
  • Scikit-learn GaussianMixture 实战:3种协方差矩阵对比与聚类效果可视化
  • OpenCV 自定义 LUT 实现伪彩色:从256x3数组到多光谱图像合成实战
  • SLO2016与PIC18LF46K40在工业通信中的优化实践
  • Ubuntu 18.04 systemd 服务配置:3步创建自定义开机启动守护进程
  • Postfix邮件服务器实战:从零搭建到多域互访
  • 如何30分钟搭建MetaboAnalystR代谢组学分析环境:完整配置实战指南
  • Kali Linux 2024.3 桌面环境:3种创建应用启动器方法详解与实战对比
  • 从WSA到.NET:Windows 11系统文件与用户配置的免重装修复指南
  • AnythingLLM:企业级私有知识库的架构革新与实践
  • 【Linux】yum与rpm实战:从依赖解析到离线部署的完整指南
  • CentOS 8.3 U盘安装实战:3步解决“Test this media”报错与盘符识别
  • SPOOLing 技术实战:Linux 下用 3 个脚本模拟虚拟打印机队列
  • AI自我进化:从代码生成到研发飞轮,开发者如何应对工作流变革
  • TLP 1.8 多品牌笔记本充电阈值配置:ThinkPad/Dell/Framework 实测对比
  • 结肠息肉分割数据集 Kvasir-SEG 与 CVC-ClinicDB 实战:3步完成数据预处理与加载
  • Windows 批处理脚本实现WiFi连接状态监控与智能重连
  • macOS Command - xattr:从隔离属性到文件溯源,解锁扩展属性的实战应用
  • 蚁剑入门指南:从零搭建渗透测试环境与Webshell实战连接
  • ResNet 残差块 PyTorch 实现:Identity Block 与 Conv Block 的 3 点核心差异
  • Linux 网卡中断绑定实战:3步隔离CPU与手动设置smp_affinity
  • Windows 11 26H1 离线安装 .NET Framework 3.5:DISM 命令与独立安装器 2 种方案对比
  • Windows 11/10 内置 Administrator 账户启用与关闭:2条命令与3个关键风险点
  • C盘告急?揪出AppData里的“空间刺客”
  • VirtualBox 共享文件夹权限配置:解决 vboxsf 组与 sudo 的 2 种权限方案实测
  • 【Windows】告别乱码:BAT批处理创建中文文件夹的编码实战指南
  • 5步轻松下载加密视频:res-downloader跨平台资源下载工具完全指南
  • Netdata 1.45 集群监控实战:3步配置Streaming,聚合5台服务器数据
  • Linux进程替换实战:execlp与fork组合实现3种并发任务调度模式