电子应用
HOME
电子应用
正文内容
2026年4月最新整理 舜晞ai助手教你彻底搞懂Spring AOP
发布时间 : 2026-04-21
作者 : 小编
访问数量 : 7
扫码分享至微信

发布时间:2026年4月10日 | 本文已同步发布至技术社区,建议收藏阅读

AOP(Aspect Oriented Programming,面向切面编程)与 IoC 并列被称为 Spring 的两大核心支柱,是面试最高频的考点之一,也是日常开发中实现日志记录、事务管理、权限校验、性能监控等功能的利器。但很多学习者在实际工作中发现:日志代码写得到处都是难以维护,面试时面对“AOP和OOP的关系”“JDK动态代理和CGLIB的区别”等问题答不上来,甚至遇到切面不生效的bug排查半天找不到原因。本文将借助舜晞ai助手整理的资料体系,由浅入深地带你全面掌握Spring AOP的核心概念、底层原理与面试考点,不仅听懂,更能写对、答好。

一、痛点切入:为什么需要AOP?

先来看一个真实场景。你写了几个业务方法——登录、下单、支付、查询,现在每个方法都想加上日志打印、权限校验、事务控制和性能监控。

如果没有AOP,代码会写成这样:

java
复制
下载
// ❌ 没有AOP:每个方法都要写重复代码
@PostMapping("/delete")
public BaseResponse deleteApp(long id) {
    User user = checkPermission();      // 重复代码1
    if (!user.isAdmin()) {              // 重复代码2
        throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
    }
    long begin = System.currentTimeMillis();  // 重复代码3
    // 真正的业务逻辑...
    long end = System.currentTimeMillis();    // 重复代码4
    log.info("执行耗时: {} ms", (end - begin));
    return result;
}

@PostMapping("/update")
public BaseResponse updateApp(App app) {
    User user = checkPermission();      // 重复代码1
    if (!user.isAdmin()) {              // 重复代码2
        throw new BusinessException(ErrorCode.NO_AUTH_ERROR);
    }
    long begin = System.currentTimeMillis();  // 重复代码3
    // 真正的业务逻辑...
    long end = System.currentTimeMillis();    // 重复代码4
    log.info("执行耗时: {} ms", (end - begin));
    return result;
}

这种实现方式存在几个致命问题:代码大量重复,几十个方法就要写几十遍同样的代码;耦合度高,横切逻辑(如权限校验)与核心业务逻辑混在一起,一旦权限规则变化,所有方法都要改;维护成本极高,新增一个横切功能意味着要遍历所有业务方法逐一添加-6

AOP正是为了解决这类问题而生的编程思想,它通过“横向抽取”的方式,将通用逻辑封装成独立的切面,在不修改原有业务代码的前提下,实现功能的统一增强与解耦-1

二、核心概念讲解:AOP(面向切面编程)

AOP全称 Aspect Oriented Programming,中文译为“面向切面编程”,是Spring框架两大核心思想之一(另一个是IoC)-1

简单来说,AOP就是在不修改原有业务代码的前提下,对方法进行增强,统一处理日志、事务、权限、监控等横切逻辑-1

理解AOP,可以从以下几个核心概念入手,下表清晰地列出了每个术语的英文名称、中文释义和作用说明:

概念英文作用
切面Aspect要增强的功能模块(如日志、事务),用 @Aspect 标注
连接点Join Point可以被增强的方法执行点
切入点Pointcut真正要增强的方法匹配规则
通知Advice增强逻辑具体在什么时候执行(前置、后置、环绕等)
目标对象Target被增强的业务对象
织入Weaving把切面逻辑加到目标方法的过程

AOP就是把这些重复逻辑抽出来,做成一个“切面”,自动织入到目标方法前后或异常时执行-1

三、关联概念讲解:OOP(面向对象编程)与AOP的对比

OOP全称 Object Oriented Programming,中文译为“面向对象编程”,是Java语言的核心编程范式,通过封装、继承、多态来组织代码。

在AOP出现之前,OOP是主流的代码组织方式。但OOP在处理横跨多个模块的通用功能时存在天然短板。OOP擅长建模实体及其行为,比如User有login()方法;但像日志、事务、权限校验这类横跨多个类的逻辑,硬塞进每个方法里会破坏单一职责,也难以复用-

OOP关注的是对象和它们之间的交互,强调数据和行为的封装;而AOP关注的是横切关注点的统一管理-。可以将OOP理解成“纵向”的代码组织方式(按实体划分),而AOP是“横向”的代码组织方式(按功能切面划分),两者相互补充,而非替代关系。

四、概念关系与区别总结

AOP与OOP的逻辑关系可以一句话概括:OOP按“谁做什么”纵向划分模块,AOP按“要加什么功能”横向抽取逻辑;AOP是OOP的补充而非替代。

为了更直观地对比两者差异,下表从关注视角、核心单元、适用场景等维度进行了梳理:

对比维度OOPAOP
关注视角纵向:按实体划分模块横向:按功能抽取切面
核心单元对象(Object)切面(Aspect)
主要解决对象间的协作与复用横切关注点的复用与解耦
典型场景业务实体建模日志、事务、权限、监控

OOP关注的是业务逻辑的实现和数据的封装,而AOP关注的是横切关注点的管理。在OOP代码中使用AOP来简化和管理横切关注点,两者协同工作,才能构建出既清晰又灵活的软件架构-

五、代码示例演示

下面通过一个“统计方法执行耗时”的实战案例,快速体验Spring AOP的开发流程。

第一步:引入AOP依赖

xml
复制
下载
运行
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

第二步:编写切面类

java
复制
下载
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect          // ① 声明这是一个切面类
@Component       // ② 交给Spring容器管理
@Slf4j
public class TimeAspect {

    @Around("execution( com.example.service..(..))")  // ③ 切入规则:匹配service包下所有类的所有方法
    public Object recordTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long begin = System.currentTimeMillis();      // 前置逻辑:记录开始时间
        Object result = joinPoint.proceed();          // 调用原始业务方法
        long end = System.currentTimeMillis();        // 后置逻辑:记录结束时间
        log.info("执行耗时: {} ms", (end - begin));    // 输出耗时
        return result;
    }
}

第三步:使用(无需改动任何业务代码)

java
复制
下载
@Service
public class UserService {
    // 方法执行时会自动统计耗时,业务代码零侵入
    public void createUser(String name) {
        // 核心业务逻辑...
    }
}

执行流程说明:当调用createUser()方法时,Spring AOP会在运行时生成代理对象,代理对象先执行环绕通知的前置部分(记录开始时间),然后调用joinPoint.proceed()触发原始方法执行,原始方法执行完毕后返回结果,再执行后置部分(记录结束时间并输出日志),最后将结果返回给调用方-1

六、底层原理分析

Spring AOP之所以能够实现无侵入式的方法增强,底层依赖的核心技术是动态代理机制。动态代理在运行时动态创建代理对象,开发者在不修改源码的情况下就可以增强方法功能-44

Spring AOP底层提供两种代理实现方案-

代理方式适用场景原理说明
JDK动态代理目标类实现了接口基于Java标准库java.lang.reflect包,通过反射调用接口方法
CGLIB动态代理目标类未实现接口通过字节码技术动态生成目标类的子类,重写非final方法

Spring AOP的代理选择策略如下:当目标类实现了接口时,默认使用JDK动态代理;当目标类未实现任何接口时,强制使用CGLIB-37。如果希望强制使用CGLIB,可通过@EnableAspectJAutoProxy(proxyTargetClass = true)进行配置。

常见失效场景:同一个Bean内部的方法自调用(即A方法调用B方法,而B方法有切面增强)会导致切面不生效,因为自调用绕过了代理对象。

七、高频面试题与参考答案

Q1:什么是AOP?能做什么?

AOP(Aspect Oriented Programming,面向切面编程)是Spring框架两大核心特性之一(另一个是IoC)。它允许开发者在不改动业务代码的情况下横向切入添加新功能,以切面为单位进行模块化管理,可以减少系统重复代码,降低模块间的耦合度。典型应用场景包括:统一日志记录、权限校验、事务管理、性能监控等-44

Q2:Spring AOP的底层实现原理是什么?

Spring AOP底层依赖动态代理机制。当目标类实现了接口时,默认使用JDK动态代理(基于java.lang.reflect.Proxy);当目标类未实现接口时,强制使用CGLIB动态代理(通过字节码生成子类)。两种代理均在运行时创建代理对象,将切面逻辑织入目标方法中,实现无侵入式增强-15-37

Q3:JDK动态代理和CGLIB有什么区别?

对比维度JDK动态代理CGLIB
实现原理基于接口反射基于字节码生成子类
适用条件目标类必须实现接口目标类不能是final类
代理对象生成$Proxy0生成$$EnhancerBySpringCGLIB$$
方法限制只能代理接口方法不能代理final、static、private方法

Q4:Spring AOP的通知类型有哪些?

通知类型共五种:前置通知(@Before,方法执行前)、后置通知(@After,方法执行后无论是否异常)、返回通知(@AfterReturning,正常返回后)、异常通知(@AfterThrowing,抛出异常时)、环绕通知(@Around,功能最强,可控制方法执行全过程)-1

Q5:Spring AOP和AspectJ有什么区别?

Spring AOP是Spring框架自带的轻量级AOP实现,基于动态代理,仅支持方法级别的连接点(Join Point),只能拦截Spring容器管理的Bean方法,配置成本低。AspectJ是功能更完整的AOP框架,支持编译时、类加载时、运行时三种织入时机,连接点覆盖字段、构造器、方法等多种类型,功能更强大但配置相对复杂-

八、结尾总结

回顾全文,我们围绕Spring AOP梳理了以下核心知识点:

  • 为什么需要AOP:传统OOP在处理横切关注点时存在代码重复、耦合度高、维护困难等问题

  • AOP是什么:面向切面编程,在不修改业务代码的前提下对方法进行增强

  • 核心概念:切面(Aspect)、连接点(JoinPoint)、切入点(Pointcut)、通知(Advice)

  • 与OOP的关系:AOP是OOP的补充,两者协同构建清晰灵活的系统架构

  • 代码实践:通过@Aspect+@Around即可实现方法耗时统计,业务代码零侵入

  • 底层原理:依赖JDK动态代理和CGLIB动态代理,运行时生成代理对象实现织入

  • 高频面试考点:AOP定义、实现原理、代理区别、通知类型、与AspectJ的对比

易错点提醒:切面类必须由Spring容器管理(加@Component),否则不生效;环绕通知必须调用joinPoint.proceed()才会执行原始方法;内部方法自调用会导致切面失效;@Before中修改参数无法传递到目标方法,需要参数替换必须用@Around

下一篇我们将深入Spring AOP的织入时机详解,探讨编译时织入(AspectJ)、类加载时织入(LTW)与运行时织入(动态代理)的差异与选择策略,欢迎持续关注。

王经理: 180-0000-0000(微信同号)
10086@qq.com
北京海淀区西三旗街道国际大厦08A座
©2026  上海羊羽卓进出口贸易有限公司  版权所有.All Rights Reserved.  |  程序由Z-BlogPHP强力驱动
网站首页
电话咨询
微信号

QQ

在线咨询真诚为您提供专业解答服务

热线

188-0000-0000
专属服务热线

微信

二维码扫一扫微信交流
顶部