Spring AOP 核心概念:切面、通知、切点、织入

张开发
2026/4/16 9:00:36 15 分钟阅读

分享文章

Spring AOP 核心概念:切面、通知、切点、织入
提到 Spring就绕不开 AOP提到 AOP很多同学都会被「切面、通知、切点、织入」这四个核心概念搞懵觉得抽象难理解甚至越学越乱。其实 AOP 一点都不复杂它的核心就是「在不修改原有代码的前提下对代码进行增强」——比如统一日志打印、接口权限校验、异常统一处理这些都是 AOP 的典型应用。什么是 Spring AOPAOP 全称 Aspect Oriented Programming即「面向切面编程」是 Spring 两大核心特性之一另一个是 IOC。通俗来讲AOP 就像「给代码“戴帽子”」原有业务代码比如用户登录、订单支付是核心我们不需要修改这些核心代码只需要在代码执行的某个节点比如执行前、执行后动态添加一些通用功能比如日志、权限校验——这些通用功能就像“帽子”戴在核心代码上不影响核心逻辑还能实现功能复用。举个最直观的例子一个电商系统的「订单支付接口」核心逻辑是“扣减库存、扣减余额”而我们需要在支付前校验用户权限支付后打印操作日志、记录支付记录。这些“权限校验、日志打印”就是 AOP 要做的事无需修改支付接口的核心代码就能完成增强。而「切面、通知、切点、织入」就是实现这种“动态增强”的四大核心组件各司其职、协同工作。四大概念我们用「学校保安站岗」来类比四大概念帮你快速理解学校的「教学活动」比如上课、考试是核心业务保安的「站岗、登记、巡逻」是通用功能不影响教学但能保障校园安全——保安的工作就相当于 AOP 的增强逻辑而保安如何安排站岗什么时候站、在哪个门口站、怎么站就对应 AOP 四大概念。一、切点Pointcut“在哪里增强”——精准定位增强位置切点就是「明确增强的位置」相当于保安的「站岗地点」比如学校正门、侧门只有经过这些地点的人对应代码中的方法才会被增强被保安登记。在 Spring AOP 中切点的核心作用是通过表达式精准匹配需要被增强的方法过滤掉不需要增强的方法避免“无差别增强”。示例比如我们要给「所有订单相关的接口」添加日志增强那么“所有订单相关的方法”就是切点再比如只给「支付接口payOrder」添加权限校验那么“payOrder 方法”就是切点。Spring AOP 常用切点表达式// 1. 匹配指定包下的所有方法最常用 execution(* com.example.demo.service.*.*(..)) // 解读com.example.demo.service 包下的所有类、所有方法无论返回值、参数是什么 // 2. 匹配指定类的所有方法 execution(* com.example.demo.service.OrderService.*(..)) // 3. 匹配指定方法精准匹配 execution(* com.example.demo.service.OrderService.payOrder(..))关键点切点只负责「定位位置」不负责「做什么增强」。二、通知Advice“增强做什么”——定义增强逻辑通知就是「增强的具体逻辑」相当于保安的「具体工作内容」比如登记身份、测量体温明确在切点位置要做什么事。在 Spring AOP 中通知的核心作用是定义在切点方法执行的某个时机执行什么样的增强逻辑是 AOP 增强的“具体实现”。Spring AOP 5种通知类型通知的核心区别在于「执行时机不同」结合实战场景理解不用死记硬背1.前置通知Before切点方法执行「之前」执行比如接口执行前的权限校验、参数校验2.后置通知After切点方法执行「之后」执行无论是否抛出异常比如接口执行后的日志记录、资源释放3.返回通知AfterReturning切点方法「正常执行完成后」执行比如获取接口返回结果做后续处理4.异常通知AfterThrowing切点方法「抛出异常后」执行比如异常捕获、日志记录、报警5.环绕通知Around包裹切点方法可在方法执行前、执行后、异常时做处理功能最强大实战中最常用。示例比如给支付接口payOrder添加增强• 前置通知校验用户是否登录、是否有支付权限• 返回通知支付成功后记录支付金额、订单号同步到消息队列• 异常通知支付失败比如余额不足捕获异常记录错误日志提示用户。三、切面Aspect“把增强和位置绑定”——整合切点和通知切面就是「把切点和通知绑定在一起」相当于「保安的工作安排」明确“在哪个门口切点做什么工作通知”是 AOP 的核心组件将分散的增强逻辑和定位规则整合起来。在 Spring AOP 中切面的核心作用是封装切点和通知形成一个独立的模块实现增强逻辑的复用比如一个切面可以绑定多个切点和通知实现全局日志增强。简单说切面 切点 通知没有切面切点和通知就是孤立的无法完成增强。示例我们创建一个「日志切面」绑定切点和通知实现全局接口日志增强// 用 Aspect 注解标记此类为切面 Aspect Component // 交给 Spring 管理 public class LogAspect { // 1. 定义切点匹配所有 service 包下的方法 Pointcut(execution(* com.example.demo.service.*.*(..))) public void logPointcut() {} // 切点方法无实际逻辑仅用于标记 // 2. 定义通知前置通知在切点方法执行前执行 Before(logPointcut()) public void beforeLog(JoinPoint joinPoint) { // 增强逻辑打印请求方法名、参数 String methodName joinPoint.getSignature().getName(); Object[] args joinPoint.getArgs(); System.out.println(前置通知执行方法 methodName 参数 Arrays.toString(args)); } // 3. 定义通知后置通知在切点方法执行后执行 After(logPointcut()) public void afterLog() { System.out.println(后置通知方法执行完成); } }解读这个 LogAspect 就是一个切面logPointcut() 是切点定位所有 service 方法beforeLog 和 afterLog 是通知定义日志增强逻辑两者通过注解绑定实现全局日志增强。四、织入Weaving“何时增强”——将切面应用到目标对象的过程织入就是「把切面的增强逻辑动态添加到目标对象核心业务代码的过程」相当于「保安到岗执行工作」的过程——把“站岗安排切面”落地到实际场景中。在 Spring AOP 中织入的核心作用是将切面的增强逻辑在指定时机编译期、类加载期、运行期融入到目标对象的方法中完成动态增强且不修改目标对象的原有代码。Spring AOP 织入时机Spring AOP 采用「运行期织入」最灵活也是实战中唯一使用的方式• 编译期织入在代码编译时将增强逻辑融入目标类需要特殊编译器不常用• 类加载期织入在目标类加载到 JVM 时将增强逻辑融入需要自定义类加载器较少用• 运行期织入在程序运行时通过 Spring 动态代理JDK 动态代理、CGLIB 代理动态生成目标对象的代理对象将切面增强逻辑融入代理对象中——无需修改原有代码灵活高效Spring 默认采用这种方式。示例当我们启动 Spring 项目时Spring 会自动扫描 Aspect 标记的切面通过动态代理将切面中的增强逻辑通知织入到切点匹配的方法中。比如我们调用 OrderService 的 payOrder 方法时Spring 会生成 OrderService 的代理对象先执行前置通知权限校验再执行 payOrder 核心逻辑最后执行后置通知日志记录——这个“动态代理增强逻辑融入”的过程就是织入。四大概念的关系用一句话总结四大概念的协同关系通过「织入」过程将「切面」包含「切点」和「通知」动态应用到目标对象实现不修改核心代码的增强。1. 切点定位“要增强的方法”在哪里加2. 通知定义“增强的逻辑”加什么3. 切面绑定切点和通知把“在哪里加”和“加什么”整合4. 织入将切面的增强逻辑动态融入目标方法怎么加何时加。注意事项混淆切点和通知❌ 错误认知以为切点就是增强逻辑✅ 正确区分切点只负责“定位位置”通知负责“执行逻辑”两者必须绑定在切面中才能实现增强。忘记给切面加 Component 注解❌ 错误做法只加 Aspect 标记切面忘记加 Component✅ 正确做法Aspect 只是标记此类是切面必须加 Component 交给 Spring 管理Spring 才能扫描到切面完成织入。文末小结其实 Spring AOP 四大核心概念本质就是“分工协作”切点找位置、通知做事情、切面整合成模块、织入落地执行最终实现“无侵入式增强”。同学们在学习时不用死记硬背术语结合「保安站岗」的类比再对照实战案例就能快速理解后续学习 AOP 实战比如全局日志、权限校验再回头看这四个概念会发现一切都很简单。如果你在学习 AOP 时遇到过困惑或者有更好的理解方法欢迎在评论区留言交流一起避坑、一起进步别忘了点赞在看收藏三连关注我解锁更多 Spring 实战干货下期再见❤️

更多文章