Spring AOP原理:从代理到拦截链

目录

  1. 引言
  2. AOP核心概念
  3. JDK动态代理原理
  4. CGLIB代理原理
  5. ProxyFactory核心逻辑
  6. Advisor和Advice体系
  7. Pointcut切点匹配
  8. AOP拦截链执行
  9. 源码流程解析
  10. 实战:自定义AOP
  11. 总结

引言

AOP(Aspect-Oriented Programming,面向切面编程)是Spring框架的核心功能之一,它允许开发者将横切关注点(如日志、事务、安全)与业务逻辑分离。

理解Spring AOP的底层原理,对于深入掌握Spring框架、设计可扩展的系统架构具有重要意义。

本文将从源码层面深入剖析:

  • JDK动态代理和CGLIB代理的实现原理
  • ProxyFactory如何创建代理对象
  • Advisor和Advice的体系结构
  • Pointcut切点匹配机制
  • AOP拦截链的执行流程

1. AOP核心概念

1.1 核心术语

代理对象 Proxy

目标对象 Target

拦截链 InterceptorChain

切面 Aspect

Advice (WHEN - 何时切)

@Before

@After

@Around

@AfterReturning

@AfterThrowing

Pointcut (WHERE - 在哪切)

execution

@annotation

within

args

被代理的真实对象
包含核心业务逻辑

Advice 1
(前置)

Advice 2
(环绕)

Advice 3
(后置)

1.2 Advice执行时机

@Aspect
@Component
public class LoggingAspect {
    
    // 1. 前置通知 - 方法执行前
    @Before("execution(* com.example.service.*.*(..))")
    public void before(JoinPoint joinPoint) {
        System.out.println("方法执行前: " + joinPoint.getSignature());
    }
    
    // 2. 后置通知 - 方法执行后(无论是否异常)
    @After("execution(* com.example.service.*.*(..))")
    public void after(JoinPoint joinPoint) {
        System.out.println("方法执行后");
    }
    
    // 3. 返回通知 - 方法正常返回后
    @AfterReturning(pointcut = "execution(* com.example.service.*.*(..))",
                   returning = "result")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        System.out.println("方法返回: " + result);
    }
    
    // 4. 异常通知 - 方法抛出异常后
    @AfterThrowing(pointcut = "execution(* com.example.service.*.*(..))",
                   throwing = "ex")
    public void afterThrowing(JoinPoint joinPoint, Exception ex) {
        System.out.println("方法异常: " + ex.getMessage());
    }
    
    // 5. 环绕通知 - 完全控制方法执行
    @Around("execution(* com.example.service.*.*(..))")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("环绕-前置");
        
        try {
            Object result = joinPoint.proceed();  // 执行目标方法
            System.out.println("环绕-返回");
            return result;
        } catch (Throwable ex) {
            System.out.println("环绕-异常");
            throw ex;
        } finally {
            System.out.println("环绕-后置");
        }
    }
}

2. JDK动态代理原理

2.1 Proxy类核心方法

public class Proxy implements java.io.Serializable {
    
    // 代理类的缓存(类加载器 -> 代理类映射)
    private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
        proxyClassCache = new WeakCache<>();
    
    // InvocationHandler
    protected InvocationHandler h;
    
    /**
     * 创建代理实例
     */
    @CallerSensitive
    public static Object newProxyInstance(
            ClassLoader loader,           // 类加载器
            Class<?>[] interfaces,        // 代理实现的接口
            InvocationHandler h) {         // 方法调用处理器
        
        // 1. 检查接口
        Objects.requireNonNull(interfaces);
        
        // 2. 获取或生成代理类
        Class<?> cl = getProxyClass0(loader, interfaces);
        
        // 3. 获取构造函数
        try {
            Constructor<?> cons = cl.getConstructor(InvocationHandler.class);
            return cons.newInstance(new Object[]{h});
        } catch (NoSuchMethodException | IllegalAccessException e) {
            throw new InternalError(e.toString(), e);
        }
    }
    
    // 获取代理类
    private static Class<?> getProxyClass0(ClassLoader loader, 
                                           Class<?>[] interfaces) {
        // 使用缓存
        return proxyClassCache.get(loader, interfaces, 
            () -> proxyGenerator.generateProxyClass(
                "$Proxy0", interfaces, 
                new Class<?>[] {java.lang.reflect.ProxyInvocationHandler.class}));
    }
}

2.2 InvocationHandler接口

public interface InvocationHandler {
    
    /**
     * 处理代理方法调用
     * @param proxy  代理对象
     * @param method 被调用的方法
     * @param args   方法参数
     * @return 方法返回值
     */
    Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
}

2.3 JDK代理实现示例

public class JdkDynamicProxyDemo {
    
    public static void main(String[] args) {
        // 1. 创建目标对象
        UserService target = new UserServiceImpl();
        
        // 2. 创建InvocationHandler
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) 
                    throws Throwable {
                
                // 前置增强
                System.out.println("Before: " + method.getName());
                
                // 执行目标方法
                Object result = method.invoke(target, args);
                
                // 后置增强
                System.out.println("After: " + method.getName());
                
                return result;
            }
        };
        
        // 3. 创建代理对象
        UserService proxy = (UserService) Proxy.newProxyInstance(
            target.getClass().getClassLoader(),
            target.getClass().getInterfaces(),
            handler
        );
        
        // 4. 调用代理方法
        proxy.addUser(new User());
    }
}

2.4 生成的代理类结构

// Spring生成的代理类示例(反编译)
public final class $Proxy0 extends Proxy implements UserService {
    
    private static Method m1;  // equals
    private static Method m2;  // toString
    private static Method m3;  // addUser
    private static Method m0;  // hashCode
    
    static {
        m1 = Class.forName("java.lang.Object").getMethod("equals", ...);
        m3 = Class.forName("com.example.UserService")
            .getMethod("addUser", User.class);
        // ...
    }
    
    public $Proxy0(InvocationHandler h) {
        super(h);
    }
    
    // 调用InvocationHandler
    @Override
    public void addUser(User user) {
        try {
            // 调用InvocationHandler.invoke()
            this.h.invoke(this, m3, new Object[]{user});
        } catch (RuntimeException | Error e) {
            throw e;
        } catch (Throwable e) {
            throw new UndeclaredThrowableException(e);
        }
    }
}

3. CGLIB代理原理

3.1 CGLIB核心概念

代理类 Proxy

目标类 Target

运行时字节码生成

addUser()
(真实逻辑)

addUser()
(拦截+增强)

CGLIB运行时生成:
• 继承目标类
• 重写所有非final方法
• MethodInterceptor拦截方法调用

3.2 MethodInterceptor接口

public interface MethodInterceptor extends Callback {
    
    /**
     * 拦截方法调用
     * @param proxy     代理对象
     * @param method    被拦截的方法
     * @param args      方法参数
     * @param methodProxy 方法代理(用于调用父类方法)
     * @return 方法返回值
     */
    Object intercept(Object proxy, Method method, Object[] args,
                    MethodProxy methodProxy) throws Throwable;
}

3.3 CGLIB代理实现示例

public class CglibProxyDemo {
    
    public static void main(String[] args) {
        // 1. 创建增强器
        Enhancer enhancer = new Enhancer();
        
        // 2. 设置父类(目标类)
        enhancer.setSuperclass(UserServiceImpl.class);
        
        // 3. 设置回调
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object proxy, Method method, 
                                   Object[] args, MethodProxy methodProxy) 
                    throws Throwable {
                
                // 前置增强
                System.out.println("Before: " + method.getName());
                
                // 调用父类方法(目标方法)
                Object result = methodProxy.invokeSuper(proxy, args);
                
                // 后置增强
                System.out.println("After: " + method.getName());
                
                return result;
            }
        });
        
        // 4. 创建代理对象
        UserServiceImpl proxy = (UserServiceImpl) enhancer.create();
        
        // 5. 调用代理方法
        proxy.addUser(new User());
    }
}

3.4 CGLIB vs JDK代理

JDK动态代理

+实现接口

+必须实现接口

+反射调用,较慢

+实现相同接口的类

+无法代理接口方法

CGLIB代理

+继承类

+非final类

+直接调用,较快

+继承目标类的子类

+无法代理final/private/static

Spring默认选择:\n• 目标类有接口 → 使用JDK代理

• 目标类无接口 → 使用CGLIB代理

代理方式对比
特性 JDK动态代理 CGLIB代理
代理方式 实现接口 继承类
目标类要求 必须实现接口 非final类
性能 反射调用,较慢 直接调用,较快
生成类 实现相同接口的类 继承目标类的子类
无法代理的方法 接口方法 final、private、static

4. ProxyFactory核心逻辑

4.1 ProxyFactory类结构

public class ProxyFactory extends ProxyCreatorSupport {
    
    // 创建代理的核心方法
    public Object getProxy() {
        return createAopProxy().getProxy();
    }
    
    public Object getProxy(ClassLoader classLoader) {
        return createAopProxy().getProxy(classLoader);
    }
    
    // 选择代理方式
    protected final AopProxy createAopProxy() {
        // 1. 检查是否应该使用CGLIB
        if (optimize || 
            proxyTargetClass ||     // 配置了proxy-target-class
            hasNoUserSuppliedProxyInterfaces()) {  // 没有接口
            
            return new CglibAopProxy(this);
        }
        
        // 2. 否则使用JDK代理
        return new JdkDynamicAopProxy(this);
    }
}

4.2 AopProxy接口

public interface AopProxy {
    
    /**
     * 创建代理对象
     */
    Object getProxy();
    
    /**
     * 使用指定类加载器创建代理对象
     */
    Object getProxy(ClassLoader classLoader);
}

4.3 JdkDynamicAopProxy实现

class JdkDynamicAopProxy implements AopProxy, InvocationHandler {
    
    private final AdvisedSupport advised;
    
    // 实现InvocationHandler
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) 
            throws Throwable {
        
        MethodInvocation invocation;
        
        // 1. 创建方法调用链
        invocation = new ReflectiveMethodInvocation(
            proxy, target, method, args, targetClass, chain);
        
        // 2. 执行拦截链
        return invocation.proceed();
    }
    
    @Override
    public Object getProxy() {
        return getProxy(target.getClass().getClassLoader());
    }
    
    @Override
    public Object getProxy(ClassLoader classLoader) {
        return Proxy.newProxyInstance(classLoader, 
            getProxiedInterfaces(), this);
    }
}

4.4 CglibAopProxy实现

class CglibAopProxy implements AopProxy {
    
    private final AdvisedSupport advised;
    
    @Override
    public Object getProxy() {
        return getProxy(classLoader);
    }
    
    @Override
    public Object getProxy(ClassLoader classLoader) {
        // 1. 创建Enhancer
        Enhancer enhancer = new Enhancer();
        
        // 2. 设置父类
        enhancer.setSuperclass(aopProxyConfig.getTargetClass());
        
        // 3. 设置回调
        enhancer.setCallbackFilter(new ProxyCallbackFilter(
            aopProxyConfig.getAdvisors()));
        
        enhancer.setCallbacks(new Callback[]{
            new DynamicAdvisedInterceptor(aopProxyConfig)
        });
        
        // 4. 创建代理
        return enhancer.create();
    }
}

// CGLIB回调拦截器
class DynamicAdvisedInterceptor implements MethodInterceptor {
    
    @Override
    public Object intercept(Object proxy, Method method, 
                            Object[] args, MethodProxy methodProxy) {
        
        // 1. 获取适用于该方法的Advisor
        List<Object> chain = getInterceptors(method);
        
        // 2. 创建CglibMethodInvocation
        CglibMethodInvocation invocation = 
            new CglibMethodInvocation(
                proxy, target, method, args, methodProxy, chain);
        
        // 3. 执行拦截链
        return invocation.proceed();
    }
}

5. Advisor和Advice体系

5.1 接口层次结构

实现

继承

IntroductionAdvisor

类级别的拦截

IntroductionInterceptor

PointcutAdvisor

Pointcut + Advice

方法级别的切面

Advice (通知)

BeforeAdvice

AfterAdvice

AroundAdvice

ThrowsAdvice

Interceptor (拦截器)

MethodBeforeInterceptor

MethodAfterInterceptor

MethodAroundAdvice

ThrowsAdviceInterceptor

Advisor (切面)

PointcutAdvisor

IntroductionAdvisor

5.2 Advice接口定义

// 基础通知接口
public interface Advice {}

// 前置通知
public interface MethodBeforeAdvice extends Advice {
    void before(Method method, Object[] args, Object target) throws Throwable;
}

// 后置通知
public interface AfterReturningAdvice extends Advice {
    void afterReturning(Object returnValue, Method method, 
                       Object[] args, Object target) throws Throwable;
}

// 环绕通知
public interface MethodInterceptor extends Interceptor {
    Object invoke(MethodInvocation invocation) throws Throwable;
}

// 异常通知
public interface ThrowsAdvice extends Advice {}

5.3 PointcutAdvisor

public interface PointcutAdvisor extends Advisor {
    
    /**
     * 获取切点
     */
    Pointcut getPointcut();
}

// 通用切面实现
public class DefaultPointcutAdvisor extends AbstractGenericPointcutAdvisor 
        implements Serializable {
    
    private Pointcut pointcut = Pointcut.TRUE;
    
    public DefaultPointcutAdvisor(Advice advice) {
        setAdvice(advice);
    }
    
    public DefaultPointcutAdvisor(Pointcut pointcut, Advice advice) {
        this.pointcut = pointcut;
        setAdvice(advice);
    }
    
    @Override
    public Pointcut getPointcut() {
        return this.pointcut;
    }
}

5.4 AspectJPointcutAdvisor

// Spring对@Aspect注解的支持
public class AspectJPointcutAdvisor extends AbstractAspectJPointcutAdvisor {
    
    private final AspectJExpressionPointcut pointcut;
    private final AspectMetadata metadata;
    
    public AspectJPointcutAdvisor(
            AbstractAspectJAdvice advice,
            AspectJExpressionPointcut pointcut) {
        this.pointcut = pointcut;
        this.metadata = new AspectMetadata(advice.getDeclaringType(), 
            advice.getAspectName());
    }
}

6. Pointcut切点匹配

6.1 Pointcut接口

public interface Pointcut {
    
    /**
     * 获取类过滤器
     * 决定哪些类需要被匹配
     */
    ClassFilter getClassFilter();
    
    /**
     * 获取方法匹配器
     * 决定哪些方法需要被匹配
     */
    MethodMatcher getMethodMatcher();
    
    // 常用的Pointcut实现
    Pointcut TRUE = TruePointcut.INSTANCE;
}

public interface ClassFilter {
    
    boolean matches(Class<?> clazz);
}

public interface MethodMatcher {
    
    /**
     * 是否匹配指定方法
     */
    boolean matches(Method method, Class<?> targetClass);
    
    /**
     * 是否是运行时匹配
     * true: 每次调用都要检查参数
     * false: 可以在类加载时缓存匹配结果
     */
    default boolean isRuntime() {
        return false;
    }
}

6.2 常用Pointcut实现

// 1. 静态方法匹配(性能更好)
public class StaticMethodMatcherPointcut extends StaticMethodMatcher 
        implements Pointcut {
    
    @Override
    public ClassFilter getClassFilter() {
        return ClassFilter.TRUE;
    }
}

// 2. 动态方法匹配(支持参数检查)
public class DynamicMethodMatcherPointcut extends DynamicMethodMatcher 
        implements Pointcut {
    
    @Override
    public ClassFilter getClassFilter() {
        return ClassFilter.TRUE;
    }
    
    @Override
    public boolean isRuntime() {
        return true;
    }
}

// 3. 表达式切点
public class AspectJExpressionPointcut 
        extends AspectJExpressionPointcutAccessor {
    
    private String expression;
    
    @Override
    public boolean matches(Method method, Class<?> targetClass) {
        // 解析AspectJ表达式
        return aspectJExpressionPointcut.matchesMethodExecution(method)
            .matches(targetClass);
    }
}

6.3 AspectJ表达式切点

// 常见AspectJ表达式
execution(* com.example.service.*.*(..))                    // 方法执行
within(com.example.service.*)                               // 包/类内所有方法
this(com.example.service.UserService)                       // 代理对象类型
target(com.example.service.UserService)                      // 目标对象类型
args(String, int)                                           // 参数类型匹配
@annotation(org.springframework.transaction.Transactional)  // 注解标记
@within(org.springframework.stereotype.Component)           // 类上有注解
@target(org.springframework.transaction.Transactional)       // 运行时有注解
@args(com.example.validation.NotNull)                      // 参数类型有注解

// 组合表达式
execution(* com.example.service.*.*(..)) && args(String)
!execution(* com.example.service.AdminService.*(..))

6.4 自定义Pointcut

// 自定义日期检查切点
public class DateCheckPointcut extends StaticMethodMatcherPointcut {
    
    // 只在工作时间执行
    private static final int START_HOUR = 9;
    private static final int END_HOUR = 18;
    
    @Override
    public boolean matches(Method method, Class<?> targetClass) {
        // 检查当前时间
        Calendar calendar = Calendar.getInstance();
        int hour = calendar.get(Calendar.HOUR_OF_DAY);
        
        return hour >= START_HOUR && hour < END_HOUR;
    }
}

// 使用
Pointcut myPointcut = new DateCheckPointcut();
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(
    myPointcut, new MyAdvice());

7. AOP拦截链执行

7.1 MethodInvocation接口

public interface MethodInvocation extends Joinpoint {
    
    /**
     * 获取方法参数
     */
    Object[] getArguments();
    
    /**
     * 执行拦截链
     * 返回方法执行的返回值
     */
    Object proceed() throws Throwable;
    
    /**
     * 获取方法
     */
    Method getMethod();
}

7.2 ReflectiveMethodInvocation

public class ReflectiveMethodInvocation implements ProxyMethodInvocation {
    
    private final Object proxy;
    private final Object target;
    private final Method method;
    private final Object[] arguments;
    private final Class<?> targetClass;
    
    // 拦截器链
    private final List<?> interceptors;
    
    // 当前执行的拦截器索引
    private int currentInterceptorIndex = -1;
    
    @Override
    public Object proceed() throws Throwable {
        
        // 1. 所有拦截器执行完毕,调用目标方法
        if (this.currentInterceptorIndex == 
            this.interceptors.size() - 1) {
            return invokeJoinpoint();
        }
        
        // 2. 获取下一个拦截器
        Object interceptorOrInterceptionAdvice = 
            this.interceptors.get(++this.currentInterceptorIndex);
        
        // 3. 调用拦截器
        if (interceptorOrInterceptionAdvice instanceof MethodInterceptor) {
            MethodInterceptor interceptor = 
                (MethodInterceptor) interceptorOrInterceptionAdvice;
            
            return interceptor.invoke(this);
        }
        
        return proceed();
    }
    
    protected Object invokeJoinpoint() throws Throwable {
        return ReflectionUtils.invokeMethod(
            this.method, this.target, this.arguments);
    }
}

7.3 拦截链执行流程

┌─────────────────────────────────────────────────────────────────────────────┐
│                           AOP拦截链执行流程                                    │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  调用 proxy.addUser(user)                                                    │
│         │                                                                     │
│         ▼                                                                     │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                   ExposeInvocationInterceptor                       │   │
│  │  • 暴露当前MethodInvocation到ThreadLocal                            │   │
│  │  • proceed()                                                        │   │
│  └─────────────────────────────────┬───────────────────────────────────┘   │
│                                    │                                            │
│                                    ▼                                            │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                      AspectJMethodBeforeAdvice                       │   │
│  │  • 执行@Before逻辑                                                   │   │
│  │  • method.invoke(target, args)                                       │   │
│  │  • proceed()                                                        │   │
│  └─────────────────────────────────┬───────────────────────────────────┘   │
│                                    │                                            │
│                                    ▼                                            │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                       AspectJAroundAdvice                             │   │
│  │  • 执行@Around前置逻辑                                               │   │
│  │  • joinPoint.proceed() ← 递归调用拦截链                              │   │
│  │  • 执行@Around后置/返回/异常逻辑                                      │   │
│  └─────────────────────────────────┬───────────────────────────────────┘   │
│                                    │                                            │
│                                    ▼                                            │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │                      AspectJAfterReturningAdvice                      │   │
│  │  • 执行@AfterReturning逻辑                                           │   │
│  │  • proceed()                                                        │   │
│  └─────────────────────────────────┬───────────────────────────────────┘   │
│                                    │                                            │
│                                    ▼                                            │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
### 7.3 拦截链执行流程

```mermaid
flowchart TB
    A["调用 proxy.addUser(user)"] --> B["ExposeInvocationInterceptor<br/>暴露ThreadLocal<br/>proceed()"]
    B --> C["AspectJMethodBeforeAdvice<br/>执行@Before逻辑<br/>proceed()"]
    C --> D["AspectJAroundAdvice<br/>执行@Around前置逻辑<br/>joinPoint.proceed() ← 递归"]
    D --> E["AspectJAfterReturningAdvice<br/>执行@AfterReturning逻辑<br/>proceed()"]
    E --> F["AspectJAfterAdvice<br/>执行@After逻辑(finally)<br/>proceed()"]
    F --> G["AspectJAfterThrowingAdvice<br/>执行@AfterThrowing逻辑<br/>proceed()"]
    G --> H["Target (目标方法)<br/>执行业务逻辑<br/>返回结果或抛异常"]
    H --> I["返回值逐层返回"]

    style A fill:#fff9c4
    style H fill:#c8e6c9
    style I fill:#e3f2fd

│ │ • 执行@After逻辑(finally) │ │
│ │ • proceed() │ │
│ └─────────────────────────────────┬───────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ AspectJAfterThrowingAdvice │ │
│ │ • 执行@AfterThrowing逻辑 │ │
│ │ • proceed() │ │
│ └─────────────────────────────────┬───────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────────────┐ │
│ │ Target (目标方法) │ │
│ │ • 真正执行业务逻辑 │ │
│ │ • 返回结果或抛出异常 │ │
│ └─────────────────────────────────┬───────────────────────────────────┘ │
│ │ │
│ ┌─────────────────────────────────┴───────────────────────────────────┐ │
│ │ 返回值逐层返回 │ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────────────────┘


### 7.4 异常处理流程

```java
// AspectJAfterThrowingAdvice
public class AspectJAfterThrowingAdvice extends AbstractAspectJAdvice 
        implements MethodInterceptor {
    
    @Override
    public Object invoke(MethodInvocation mi) throws Throwable {
        try {
            return mi.proceed();
        } catch (Throwable ex) {
            // 只有匹配的异常类型才执行通知
            if (matchesThrownType(ex.getClass())) {
                invokeAdviceMethod(
                    getJoinPointMatch(),  // 切入点匹配结果
                    null,                 // 返回值(异常时为null)
                    ex                   // 异常对象
                );
            }
            throw ex;  // 重新抛出异常
        }
    }
}

8. 源码流程解析

8.1 自动代理创建者

// AnnotationAwareAspectJAutoProxyCreator
public class AnnotationAwareAspectJAutoProxyCreator 
        extends AspectJAwareAdvisorAutoProxyCreator {
    
    @Override
    public Object postProcessAfterInitialization(
            Object bean, String beanName) throws BeansException {
        
        // 1. 判断是否应该被代理
        if (isInfrastructureClass(bean.getClass()) || 
            shouldSkip(beanName, getBeanDefinition(beanName))) {
            return bean;
        }
        
        // 2. 创建代理
        Object proxy = createProxy(
            bean.getClass(),
            beanName,
            getInterceptorsAndDynamicInterceptionAdvice(
                bean.getClass(), beanName),
            new SingletonTargetSource(bean));
        
        return proxy;
    }
    
    // 获取拦截器链
    protected List<Object> getInterceptorsAndDynamicInterceptionAdvice(
            Class<?> beanClass, String beanName) {
        
        List<Object> chain = new ArrayList<>();
        
        // 1. 获取所有Advisor
        List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
        
        // 2. 为每个Advisor创建MethodInterceptor
        for (Advisor advisor : advisors) {
            if (advisor instanceof PointcutAdvisor) {
                PointcutAdvisor pca = (PointcutAdvisor) advisor;
                
                // 检查是否匹配
                if (pca.getPointcut().getMethodMatcher()
                    .matches(method, targetClass)) {
                    chain.add(advisor);
                }
            }
        }
        
        return chain;
    }
}

8.2 Advisor查找

// BeanFactoryAdvisorRetrievalHelper
public class BeanFactoryAdvisorRetrievalHelper {
    
    public List<Advisor> findAdvisorBeans() {
        // 1. 获取所有Advisor Bean
        String[] advisorNames = beanFactory.getBeanNamesForType(
            Advisor.class, true, false);
        
        // 2. 创建Advisor列表
        List<Advisor> advisors = new ArrayList<>();
        for (String name : advisorNames) {
            if (isEligible(name)) {
                advisors.add(beanFactory.getBean(name));
            }
        }
        
        return advisors;
    }
}

9. 实战:自定义AOP

9.1 自定义@Around注解

// 定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyCacheable {
    
    String key();
    
    int expireSeconds() default 300;
}

// 切面实现
@Aspect
@Component
public class MyCacheAspect {
    
    private Map<String, CacheEntry> cache = new ConcurrentHashMap<>();
    
    @Around("@annotation(myCacheable)")
    public Object around(ProceedingJoinPoint joinPoint, 
                         MyCacheable myCacheable) throws Throwable {
        
        // 1. 生成缓存key
        String key = myCacheable.key();
        
        // 2. 检查缓存
        CacheEntry entry = cache.get(key);
        if (entry != null && !entry.isExpired()) {
            return entry.getValue();  // 返回缓存值
        }
        
        // 3. 执行方法
        Object result = joinPoint.proceed();
        
        // 4. 存入缓存
        cache.put(key, new CacheEntry(result, 
            myCacheable.expireSeconds()));
        
        return result;
    }
}

class CacheEntry {
    private final Object value;
    private final long expireTime;
    
    CacheEntry(Object value, int ttlSeconds) {
        this.value = value;
        this.expireTime = System.currentTimeMillis() + ttlSeconds * 1000;
    }
    
    boolean isExpired() {
        return System.currentTimeMillis() > expireTime;
    }
    
    Object getValue() {
        return value;
    }
}

9.2 自定义方法拦截器

@Component
public class PerformanceMonitorInterceptor implements MethodInterceptor {
    
    private static final Logger logger = LoggerFactory.getLogger(
        PerformanceMonitorInterceptor.class);
    
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        
        String className = invocation.getThis().getClass().getSimpleName();
        String methodName = invocation.getMethod().getName();
        
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        
        try {
            return invocation.proceed();
        } finally {
            stopWatch.stop();
            
            if (stopWatch.getTotalTimeMillis() > 100) {
                logger.warn("方法执行过慢: {}.{} - {}ms", 
                    className, methodName, 
                    stopWatch.getTotalTimeMillis());
            }
        }
    }
}

// 配置
@Configuration
public class AopConfig {
    
    @Bean
    public Advisor performanceMonitorAdvisor() {
        return new DefaultPointcutAdvisor(
            new AspectJExpressionPointcut(),
            new PerformanceMonitorInterceptor()
        );
    }
}

总结

本文深入剖析了Spring AOP的底层原理:

代理机制:

  • JDK动态代理:通过实现接口创建代理
  • CGLIB代理:通过继承类创建代理
  • Spring根据目标类是否有接口自动选择代理方式

核心组件:

  • ProxyFactory:统一创建代理对象
  • Advice:通知,包含增强逻辑
  • Advisor:切面,包含Pointcut + Advice
  • Pointcut:切点,决定在哪里拦截

拦截链执行:

  • MethodInterceptor链式调用
  • proceed()方法控制执行顺序
  • 异常处理会逐层传播

执行流程:

  1. 创建代理 → JdkDynamicAopProxy/CglibAopProxy
  2. 方法调用 → InvocationHandler.invoke()
  3. 执行拦截链 → ReflectiveMethodInvocation.proceed()
  4. 调用目标方法 → 最终执行

理解这些核心机制,对于编写高质量的AOP应用和问题排查至关重要。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐