AOP学习 + 高频面试题 + 标准答案。
🚀 一、Mini-AOP(最小可运行理解版)
核心思想:
AOP = 用动态代理生成一个代理对象
→ 在方法前后加“增强逻辑”
→ 再调用原始对象的方法
我们用 JDK 动态代理写一个最小版本。
🟦 Step 1:定义一个接口(JDK 代理要求接口)
public interface UserService {
void register();
}
🟦 Step 2:实现类
public class UserServiceImpl implements UserService {
@Override
public void register() {
System.out.println("执行注册业务逻辑");
}
}
🟦 Step 3:写一个 AOP 代理(核心代码!)
import java.lang.reflect.*;
public class AOPProxy {
public static Object getProxy(Object target) {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// ⭐ 方法执行前增强
System.out.println("【before】方法执行前:记录日志");
Object result = method.invoke(target, args);
// ⭐ 方法执行后增强
System.out.println("【after】方法执行后:记录日志");
return result;
}
}
);
}
}
这段小代码就是 Spring AOP 的本质。
🟦 Step 4:测试 mini-AOP
public class Main {
public static void main(String[] args) {
UserService target = new UserServiceImpl();
UserService proxy = (UserService) AOPProxy.getProxy(target);
proxy.register();
}
}
输出:
【before】方法执行前:记录日志
执行注册业务逻辑
【after】方法执行后:记录日志
🎉 你现在理解了:
- Spring AOP = 自动帮你生成这个代理对象
- 代理对象 = 你的 Bean + 增强逻辑
- IOC = 负责把“代理对象”注入,而不是“原始对象”
这就是 AOP 的核心!
🧠 二、AOP 高频面试题 + 标准答案(简短但非常专业)
⭐ 1. 什么是 AOP?(必考)
AOP(面向切面编程)是在不修改业务代码的情况下,为方法统一添加横切逻辑(如日志、事务、权限)的机制,通过动态代理在方法执行前后织入增强。
⭐ 2. AOP 的核心概念有哪些?
- 切面(Aspect):增强逻辑的模块
- 通知(Advice):前置/后置/环绕逻辑
- 切点(Pointcut):哪些方法被增强
- 连接点(JoinPoint):具体的增强位置
- 织入(Weaving):增强逻辑加入业务逻辑的过程
⭐ 3. Spring AOP 是如何实现的?
基于动态代理:如果类有接口用 JDK Proxy,没有接口使用 CGLIB 生成子类。
容器最终注入的是代理对象而不是原始对象。
⭐ 4. JDK Proxy 和 CGLIB 的区别?
| JDK Proxy | CGLIB |
|---|---|
| 基于接口 | 基于继承 |
| 必须有接口 | 不需要接口 |
| 性能略慢 | 性能更好 |
| 代理接口 | 代理类 |
问得最多的一句:
final 类/方法不能使用 CGLIB,因为无法继承或重写。
⭐ 5. 为什么 @Transactional 有时会失效?
最常见的原因:
- 方法不是 public(事务只作用于 public 方法)
- 在同一个类里内部调用(没有经过代理对象)
- final 方法无法被代理
- 类标注 @Transactional 但方法没有 public
最核心一句:
内部调用没有经过代理对象,AOP 不生效。
⭐ 6. @Around 和 @Before/@After 的区别?
- @Before/@After:只包裹方法前/后,不控制方法执行
- @Around:完全控制方法执行,可决定是否执行原方法
面试官爱听一句:
@Around 是最强大的通知,因为它能用 ProceedingJoinPoint 控制整个方法链。
⭐ 7. Spring AOP 和 AspectJ 的区别?
- Spring AOP:运行时,动态代理,功能有限,但足够业务
- AspectJ:编译时织入,功能强大,多用于框架
面试标准回答:
Spring AOP 是基于代理的“轻量级 AOP”,适合业务增强;
AspectJ 是“完整 AOP 方案”,功能更广,但不常用于普通业务。
⭐ 8. 构造器能否被 AOP 增强?
不能。
原因:
对象构造时代理对象还没创建出来,因此无法增强构造器。
⭐ 9. AOP 为什么依赖 IOC?
因为 AOP 会生成代理对象,如果没有 IOC,业务代码无法自动替换成代理对象,增强就无法生效。
⭐ 10. 你在实际项目中怎么用 AOP?
可以说:
- 日志记录
- 统一异常处理
- 性能监控
- API 参数校验
- 权限控制
- 事务管理(@Transactional)
Top comments (0)