Spring AI应用助手带你吃透Spring AOP:从动态代理到高频面试题(2026年4月9日)

小编头像

小编

管理员

发布于:2026年04月28日

3 阅读 · 0 评论

2026年开年以来,Spring生态持续活跃——3月13日Spring Framework 6.2.17与7.0.6接连发布,3月下旬Spring Boot 4.1.0的第三个里程碑版本也已亮相-11。无论技术栈如何迭代,Spring AOP始终是开发者绕不开的核心模块。然而很多初学者陷入了“会用但不原理”的困境:知道@Transactional能回滚事务,却说不出失效原因;面试被问“JDK动态代理和CGLIB区别”时语焉不详。本文以Spring AI应用助手串联资料的方式,从代码痛点切入,到概念梳理、底层原理再到面试考点,帮你建立完整的知识链路。

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

先看一段“反面教材”。假设我们要为UserService的所有方法添加日志记录,传统OOP的做法是在每个方法中手动添加日志代码:

java
复制
下载
@Service

public class UserService { public void saveUser(User user) { System.out.println("【日志】开始保存用户"); // 日志代码侵入业务 // 核心业务逻辑... System.out.println("【日志】用户保存成功"); } public void deleteUser(Long id) { System.out.println("【日志】开始删除用户"); // 日志代码重复 // 核心业务逻辑... System.out.println("【日志】用户删除成功"); } }

这段代码的问题一目了然:代码重复(每个方法都要写日志)、耦合度高(业务逻辑与非功能性代码混杂)、维护困难(修改日志格式要找遍所有方法)。统计数据显示,传统OOP在处理日志、事务等横切关注点时,代码重复率可高达60%以上-20。这正是AOP要解决的问题。

二、核心概念讲解:AOP(Aspect-Oriented Programming)

AOP,全称 Aspect-Oriented Programming(面向切面编程),是一种编程范式,核心思想是在不修改业务源代码的前提下,为程序主干功能动态添加增强逻辑-26

生活化类比:把业务方法想象成“高速公路主路”,日志、事务、权限校验就像“收费站”“监控摄像头”。传统做法是在主路上直接建收费站,AOP的做法则是单独建一套“辅助设施系统”,动态地“织入”到主路各处,主路代码本身完全不受影响。

AOP的核心术语用一句话串起来:切点(Pointcut) 决定“哪些方法需要被增强”,通知(Advice) 定义“增强什么逻辑”,二者组合成 切面(Aspect) ,在运行时通过 织入(Weaving) 应用到目标对象-21-26

三、关联概念讲解:AspectJ

AspectJ 是目前Java生态中功能最强大的AOP框架,通过编译时或类加载时织入切面逻辑,支持方法、构造器、字段等更丰富的连接点类型-21

对比维度Spring AOPAspectJ
织入时机运行时动态代理编译时/类加载时织入
连接点范围仅方法级别方法、构造器、字段等
性能运行时略有开销编译时优化,性能更高
使用场景日常业务(日志、事务)复杂框架级需求

一句话总结:Spring AOP ≈ 轻量级运行时AOP(依赖动态代理),AspectJ ≈ 重量级全功能AOP(编译时织入)。大多数业务场景下,Spring AOP已足够;需要更精细控制时才引入AspectJ。

四、底层原理:动态代理与CGLIB

Spring AOP的底层依赖两个核心技术:JDK动态代理CGLIB。通过DefaultAopProxyFactory智能选择代理策略:若目标类实现了接口且未强制指定CGLIB,使用JDK代理;否则使用CGLIB-26

JDK动态代理

前置条件:目标类必须实现至少一个接口。底层通过java.lang.reflect.ProxyInvocationHandler,在运行时动态生成实现目标接口的代理类,所有方法调用经invoke()方法转发,在此处插入增强逻辑-21

CGLIB代理

适用场景:目标类没有实现接口。CGLIB通过字节码技术动态生成目标类的子类作为代理,在子类中重写父类方法并插入增强逻辑。需注意:final类或final方法无法被CGLIB代理-21

性能对比

JDK动态代理基于反射机制,而CGLIB生成的代理类是直接调用,通常CGLIB性能更优;但JDK无需引入第三方依赖,实现更轻量-39

五、代码示例:Spring Boot中实战AOP

Spring Boot为AOP提供了自动配置,只需三步即可上手-50

第1步:添加依赖(pom.xml)

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

第2步:创建切面类

java
复制
下载
@Aspect
@Component
public class LogAspect {
    // 切入点:匹配service包下所有类的所有方法
    @Pointcut("execution( com.example.service..(..))")
    public void serviceMethod() {}
    
    @Before("serviceMethod()")
    public void logBefore(JoinPoint joinPoint) {
        System.out.println("【前置通知】方法:" + joinPoint.getSignature().getName() 
            + ",参数:" + Arrays.toString(joinPoint.getArgs()));
    }
    
    @AfterReturning(pointcut = "serviceMethod()", returning = "result")
    public void logAfterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("【返回通知】返回值:" + result);
    }
    
    @Around("serviceMethod()")
    public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
        Object result = joinPoint.proceed();  // 执行目标方法
        long cost = System.currentTimeMillis() - start;
        System.out.println("【环绕通知】耗时:" + cost + "ms");
        return result;
    }
}

运行效果:每次调用UserService中的方法,日志自动输出,业务代码零侵入。

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

Q1:Spring AOP的实现原理是什么?JDK动态代理和CGLIB有何区别?

踩分点:动态代理 + JDK基于接口 + CGLIB基于继承 + Spring代理选择逻辑

AOP通过横向抽取共性功能解决代码重复问题,核心原理是动态代理-39。JDK动态代理基于接口实现,通过反射在运行时生成代理类,要求目标类必须实现接口;CGLIB通过继承目标类生成子类代理,无需接口支持,但不能代理final类/方法。Spring默认优先使用JDK动态代理,目标类无接口时自动切换至CGLIB-39

Q2:Spring AOP提供了哪些通知类型?

踩分点:五种通知 + 执行时机

@Before(方法执行前)、@After(方法执行后,无论是否异常)、@AfterReturning(方法正常返回后)、@AfterThrowing(方法抛出异常后)、@Around(环绕通知,通过ProceedingJoinPoint.proceed()控制执行流程,功能最强大)-21

Q3:为什么@Transactional有时会失效?

踩分点:内部调用无代理 + public限制 + final限制

最常见原因:①在同一个类中内部调用方法(未经过代理对象,AOP不生效);②方法不是public的(事务只作用于public方法);③final方法无法被代理-41

七、结尾总结

回顾全文核心要点:AOP解决的是横切关注点与业务逻辑分离的问题。Spring AOP基于动态代理在运行时织入增强,与编译时织入的AspectJ形成互补;JDK动态代理(需接口)与CGLIB(无接口)是两大底层支撑。面试高频考点集中在动态代理原理、通知类型、@Transactional失效原因三个方向。

易错提醒:切面类必须被Spring容器管理(@Component@Bean);内部方法调用不走代理,切面不生效。下一篇我们将深入Spring事务管理的底层实现,敬请期待。

标签:

相关阅读