Spring AOP实现原理与拦截器
📚2025年Java面试宝典:点击下载
(提取码:9b3g)
一、Spring AOP实现原理的核心机制
Spring AOP的实现核心是动态代理,它通过两种方式实现:JDK动态代理和CGLIB字节码增强。
- JDK动态代理:适用于目标类实现了接口的场景。代理对象会实现相同接口,并在方法调用时通过
InvocationHandler拦截逻辑。 - CGLIB代理:针对没有接口的类,通过生成目标类的子类,并重写方法实现拦截。
面试中常被问到两者的区别,可以这样回答:
"JDK动态代理基于接口,运行时生成代理类;CGLIB通过继承方式增强,性能略低但适用性更广。Spring默认优先使用JDK代理,当无接口时自动切换CGLIB。"

二、拦截器的工作流程
拦截器(Interceptor)是AOP中的核心组件,其工作流程分为三个阶段:
- 前置增强(Before Advice):在目标方法执行前触发,比如权限校验。
- 后置增强(After Advice):在方法执行后触发,无论是否异常,常用于日志记录。
- 环绕增强(Around Advice):包裹目标方法,可控制是否执行原方法,适合事务管理。
实际开发中,拦截器链(Interceptor Chain)会按顺序执行。例如,一个接口限流场景可能包含:
鉴权拦截器 → 限流拦截器 → 日志拦截器 → 目标方法
三、动态代理与字节码增强的区别
| 对比项 | JDK动态代理 | CGLIB | |------------------|--------------------------|--------------------------| | 实现方式 | 接口代理 | 子类继承 | | 性能 | 调用速度快 | 生成代理类耗时 | | 依赖 | 需目标类实现接口 | 无限制 | | 方法拦截 | 仅拦截接口方法 | 可拦截所有非final方法 |
面试中如果被问_“为什么有的场景必须用CGLIB?”_,可以结合案例:
"例如目标类没有实现接口,或者需要拦截非public方法时,CGLIB是唯一选择。"

四、拦截器的实际应用场景
- 日志记录:统一记录接口请求参数、响应时间。
- 事务管理:通过环绕增强实现事务的提交与回滚。
- 权限校验:在方法执行前检查用户角色。
- 性能监控:统计方法耗时,定位性能瓶颈。
例如,在电商系统中,下单接口可能需要以下拦截器:
风控拦截器 → 库存校验 → 优惠券核销 → 生成订单
五、Spring AOP如何与拦截器协作
Spring通过ProxyFactory类将拦截器织入目标对象。核心步骤如下:
- 定义切点(Pointcut):通过表达式匹配需要拦截的方法。
- 配置增强(Advice):实现
MethodInterceptor接口编写业务逻辑。 - 创建代理对象:根据目标类选择JDK或CGLIB生成代理。
一个典型的环绕增强代码逻辑:
public Object invoke(MethodInvocation invocation) throws Throwable {
// 前置逻辑
System.out.println("Before method: " + invocation.getMethod().getName());
// 执行目标方法
Object result = invocation.proceed();
// 后置逻辑
System.out.println("After method: " + invocation.getMethod().getName());
return result;
}
六、高频面试题解析
- Spring AOP和AspectJ有什么区别?
"Spring AOP是运行时增强,基于代理;AspectJ是编译时/类加载时增强,功能更强大但需要额外插件。"
- 拦截器中能修改方法参数吗?
"可以,在环绕增强中通过
MethodInvocation获取参数数组并修改。"
- 如何解决拦截器循环依赖问题?
"避免在拦截器中直接调用被代理的方法,改用BeanFactory获取代理对象。"

💡小贴士:如果需要购买面试鸭会员,可以通过面试鸭返利网联系我,返利25元!
(官网地址:mianshiyafanli.com)


