Spring AOP代理机制与实现源码解析
AOP 是 Spring 框架的核心特性,理解其代理机制是掌握 Spring 高级用法的关键。
AOP 核心概念
基础术语
| 术语 | 说明 |
|---|---|
| Aspect | 切面:横切关注点的模块化 |
| JoinPoint | 连接点:程序执行中的特定点 |
| Pointcut | 切入点:匹配连接点的表达式 |
| Advice | 通知:在连接点执行的动作 |
| Target | 目标对象:被代理的对象 |
| Proxy | 代理对象:AOP 创建的对象 |
| Weaving | 绑定:将切面应用到目标对象 |
Advice 类型
| 通知类型 | 注解 | 执行时机 |
|---|---|---|
| Before | @Before | 方法执行前 |
| After | @After | 方法执行后(无论成功或异常) |
| AfterReturning | @AfterReturning | 方法成功返回后 |
| AfterThrowing | @AfterThrowing | 方法抛出异常后 |
| Around | @Around | 环绕(可控制整个执行过程) |
代理模式对比
JDK 动态代理 vs CGLIB
| 特性 | JDK 动态代理 | CGLIB |
|---|---|---|
| 实现方式 | 接口代理 | 类继承代理 |
| 性能 | 较低(反射) | 较高(直接调用) |
| 限制 | 必须有接口 | 不能代理 final 类/方法 |
| Spring默认 | 有接口用 JDK | 无接口用 CGLIB |
Spring 代理选择策略
Java
// DefaultAopProxyFactory
public AopProxy createAopProxy(AdvisedSupport config) {
if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
// 使用 CGLIB
return new CglibAopProxy(config);
} else {
// 使用 JDK 动态代理
return new JdkDynamicAopProxy(config);
}
}
强制使用 CGLIB
Java
@Configuration
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class AopConfig {
// 强制所有代理使用 CGLIB
}
JDK 动态代理实现
核心源码:JdkDynamicAopProxy
Java
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler {
private final AdvisedSupport advised;
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation;
// 1. 获取拦截器链
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
// 无拦截器,直接调用目标方法
Object retVal = AopUtils.invokeJoinpointUsingReflection(target, method, args);
return retVal;
} else {
// 创建方法调用对象
invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 执行拦截器链
Object retVal = invocation.proceed();
return retVal;
}
}
}
代理对象创建
Java
@Override
public Object getProxy(ClassLoader classLoader) {
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
// 使用 JDK Proxy 创建代理
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
CGLIB 代理实现
核心源码:CglibAopProxy
Java
class CglibAopProxy implements AopProxy {
@Override
public Object getProxy(ClassLoader classLoader) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(targetClass); // 设置父类
enhancer.setClassLoader(classLoader);
enhancer.setCallback(new DynamicAdvisedInterceptor()); // 设置拦截器
return enhancer.create(); // 创建代理对象
}
private class DynamicAdvisedInterceptor implements MethodInterceptor {
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
// 获取拦截器链
List<Object> chain = advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
// 直接调用目标方法
return proxy.invoke(target, args);
} else {
// 执行拦截器链
MethodInvocation invocation = new CglibMethodInvocation(proxy, target, method, args, chain);
return invocation.proceed();
}
}
}
}
切面执行链
ReflectiveMethodInvocation
Java
public class ReflectiveMethodInvocation implements ProxyMethodInvocation {
protected final Object proxy;
protected final Object target;
protected final Method method;
protected Object[] arguments;
protected final List<?> interceptorsAndDynamicMethodMatchers;
protected int currentInterceptorIndex = -1;
@Override
public Object proceed() throws Throwable {
// 1. 判断是否已执行完所有拦截器
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
// 执行目标方法
return invokeJoinpoint();
}
// 2. 获取下一个拦截器
Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// 动态匹配
InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
if (dm.matcher.matches(this.method, this.targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
} else {
// 不匹配,继续下一个
return proceed();
}
} else {
// 静态拦截器
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
protected Object invokeJoinpoint() throws Throwable {
return AopUtils.invokeJoinpointUsingReflection(this.target, this.method, this.arguments);
}
}
执行流程图
Java
调用代理方法 → invoke()
↓
获取拦截器链 → chain
↓
ReflectiveMethodInvocation.proceed()
↓
Interceptor1.invoke(invocation)
├─ 前置逻辑
├─ invocation.proceed() → 进入下一个拦截器
└─ 后置逻辑
↓
Interceptor2.invoke(invocation)
├─ 前置逻辑
├─ invocation.proceed()
└─ 后置逻辑
↓
invokeJoinpoint() → 目标方法执行
↓
返回结果,逐层返回
@AspectJ 注解解析
切面注解处理器
Java
// AnnotationAwareAspectJAutoProxyCreator
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {
// 解析 @Aspect 注解类
protected List<Advisor> findCandidateAdvisors() {
List<Advisor> advisors = super.findCandidateAdvisors();
// 查找所有 @Aspect 类
if (this.aspectJAdvisorsBuilder != null) {
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
}
Advisor 构建
Java
// ReflectiveAspectJAdvisorFactory
public Advisor getAdvisor(Method adviceMethod, AspectJExpressionPointcut expressionPointcut, ...) {
// 解析切入点表达式
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut(expression);
// 创建 Advice
Advice advice = getAdvice(adviceMethod, pointcut, ...);
// 尝试获取 Aspect 注解中的order属性
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, advice, ...);
}
不同 Advice 的实现
Java
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut pointcut, ...) {
// @Before
if (candidateAdviceMethod.isAnnotationPresent(Before.class)) {
return new AspectJMethodBeforeAdvice(candidateAdviceMethod, pointcut, aspectInstanceFactory);
}
// @After
if (candidateAdviceMethod.isAnnotationPresent(After.class)) {
return new AspectJAfterAdvice(candidateAdviceMethod, pointcut, aspectInstanceFactory);
}
// @AfterReturning
if (candidateAdviceMethod.isAnnotationPresent(AfterReturning.class)) {
return new AspectJAfterReturningAdvice(candidateAdviceMethod, pointcut, aspectInstanceFactory);
}
// @AfterThrowing
if (candidateAdviceMethod.isAnnotationPresent(AfterThrowing.class)) {
return new AspectJAfterThrowingAdvice(candidateAdviceMethod, pointcut, aspectInstanceFactory);
}
// @Around
if (candidateAdviceMethod.isAnnotationPresent(Around.class)) {
return new AspectJAroundAdvice(candidateAdviceMethod, pointcut, aspectInstanceFactory);
}
return null;
}
事务代理机制
TransactionInterceptor 源码
Java
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
Class<?> targetClass = invocation.getThis().getClass();
Method method = invocation.getMethod();
// 获取事务属性
TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
// 获取事务管理器
PlatformTransactionManager tm = determineTransactionManager(txAttr);
// 获取事务
TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
try {
// 执行目标方法
Object retVal = invocation.proceedWithInvocation();
// 提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
} catch (Throwable ex) {
// 异常时回滚
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
} finally {
cleanupTransactionInfo(txInfo);
}
}
}
事务传播实现
Java
protected TransactionInfo createTransactionIfNecessary(PlatformTransactionManager tm, TransactionAttribute txAttr, ...) {
TransactionStatus status = null;
if (txAttr != null && tm != null) {
// 根据传播行为获取事务
status = tm.getTransaction(txAttr);
}
return new TransactionInfo(txAttr, status);
}
// AbstractPlatformTransactionManager
public final TransactionStatus getTransaction(TransactionDefinition definition) {
Object transaction = doGetTransaction();
// 已有事务存在
if (isExistingTransaction(transaction)) {
// 根据传播行为处理
return handleExistingTransaction(definition, transaction);
}
// 无现有事务
if (definition.getPropagationBehavior() == PROPAGATION_REQUIRED) {
// 开启新事务
return startTransaction(definition, transaction, true);
}
// ... 其他传播行为处理
}
自定义切面实战
Around 通知完整实现
text
@Aspect
@Component
@Slf4j
public class LoggingAspect {
@Around("execution(* com.example.service.*.*(..))")
public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {
String methodName = joinPoint.getSignature().getName();
Object[] args = joinPoint.getArgs();
log.info("Before: {} with args {}", methodName, Arrays.toString(args));
try {
Object result = joinPoint.proceed();
log.info("AfterReturning: {} result {}", methodName, result);
return result;
} catch (Throwable e) {
log.error("AfterThrowing: {} exception {}", methodName, e.getMessage());
throw e;
} finally {
log.info("After: {}", methodName);
}
}
}
切入点表达式详解
| 表达式 | 说明 |
|---|---|
| execution(public * *(..)) | 所有 public 方法 |
| execution(* set*(..)) | 所有 set 开头方法 |
| execution(* com.example.service..(..)) | service 包下所有方法 |
| execution(* com.example.service...(..)) | service 包及其子包 |
| @annotation(org.springframework.transaction.annotation.Transactional) | 有 @Transactional 的方法 |
| @within(org.springframework.stereotype.Service) | @Service 类的所有方法 |
要点总结
| 要点 | 说明 |
|---|---|
| 代理选择 | 有接口用 JDK,无接口用 CGLIB |
| JDK代理 | Proxy.newProxyInstance + InvocationHandler |
| CGLIB代理 | Enhancer + MethodInterceptor |
| 执行链 | ReflectiveMethodInvocation.proceed() |
| 切面解析 | AnnotationAwareAspectJAutoProxyCreator |
| 事务代理 | TransactionInterceptor + 传播行为处理 |
| 拦截器顺序 | 按 @Order 或声明顺序执行 |
📝 发现内容有误?点击此处直接编辑