目录
- 1. AOP核心概念
- 2. 动态代理机制
- (1)JDK动态代理
- (2)CGLIB动态代理
- 3. AOP执行流程
- 4. 与AspectJ的关系
- 总结
Spring AOP(面向切面编程)是Spring框架的核心特性之一,它基于动态代理和字节码增强技术实现,能够在不修改原有代码的情况下,为程序添加横切关注点(如日志、事务、安全等)。其核心原理可以从以下几个方面理解:
1. AOP核心概念
- 切面(Aspect):封装横切关注点的类,包含通知和切入点。
- 通知(Advice):切面的具体实现(如前置通知、后置通知等)。
- 切入点(Pointcut):定义通知作用的目标方法(通过表达式匹配)。
- 连接点(JoinPoint):程序执行过程中可插入切面的点(如方法调用、异常抛出等)。
- 代理(Proxy):AOP通过代理对象执行目标方法,并在执行前后插入通知逻辑。
2. 动态代理机制
Spring AOP的核心实现依赖动态代理,根据目标类是否实现接口,自动选择两种代理方式:
(1)JDK动态代理
- 适用场景:目标类实现了接口。
- 原理:通过
java.lang.reflect.Proxy
类在运行时动态生成代理类,代理类实现目标接口,并在接口方法中嵌入通知逻辑。 - 特点:只代理接口中的方法,不代理类中的非接口方法。
// JDK动态代理示例(简化版)
public class JdkProxy implements InvocationHandler {private Object target; // 目标对象public JdkProxy(Object target) {this.target = target;}// 生成代理对象public Object getProxy() {return Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),this);}// 代理逻辑(调用目标方法时执行)@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {// 前置通知(如日志)System.out.println("方法执行前...");// 执行目标方法Object result = method.invoke(target, args);// 后置通知System.out.println("方法执行后...");return result;}
}
(2)CGLIB动态代理
- 适用场景:目标类未实现接口。
- 原理:通过CGLIB(Code Generation Library)在运行时动态生成目标类的子类,并重写目标方法,在子类中嵌入通知逻辑。
- 特点:可代理类中的所有方法(需注意final方法无法被重写,因此不能被代理)。
3. AOP执行流程
- 解析配置:Spring容器启动时,解析AOP相关配置(如
@Aspect
、@Before
等注解或XML配置),识别切面、通知和切入点。 - 创建代理:对符合切入点匹配的目标类,Spring自动为其创建代理对象(JDK或CGLIB代理)。
- 拦截调用:当调用目标方法时,实际执行的是代理对象的方法。
- 执行通知:代理对象在目标方法执行前后(或异常时)插入通知逻辑。
- 执行目标方法:通知逻辑执行完毕后,代理对象调用原始目标类的方法。
4. 与AspectJ的关系
- Spring AOP使用了AspectJ的切入点表达式语法(如
execution(* com.example.service.*.*(..))
),但实现原理不同。 - AspectJ是基于编译期或类加载期的字节码增强,而Spring AOP是基于运行时的动态代理,更轻量且与Spring容器深度集成。
总结
Spring AOP通过动态代理技术,在不侵入业务代码的前提下,实现了横切关注点的模块化,降低了代码耦合度。其核心是通过代理对象拦截目标方法调用,并在调用过程中织入通知逻辑,从而实现日志记录、事务管理等通用功能的复用。