AOP底层实现关键的源码、方法解析

AOP底层实现关键的源码、方法解析

一、介绍

AOP(Aspect-Oriented Programming,面向切面编程)是 Spring 框架的核心特性之一,它通过代理机制实现了横切关注点的模块化。理解 AOP 的底层实现原理,对于深入掌握 Spring 框架和编写高质量代码至关重要。

本文将从源码层面深入解析 AOP 的实现机制,重点关注:

  1. 反射技术在 AOP 中的关键应用
  2. 代理对象的创建时机和动态代理类的生成阶段
  3. 基于 AOP 注解生命周期的完整执行流程

二、AOP 核心概念与架构

2.1 AOP 实现方式

Spring AOP 支持两种代理方式:

  • JDK 动态代理 :基于接口实现,使用 java.lang.reflect.ProxyInvocationHandler
  • CGLIB 代理:基于类继承实现,通过字节码增强技术生成子类

2.2 核心组件

  • Aspect:切面,包含多个切点和通知
  • Pointcut:切点,定义在哪些方法上应用通知
  • Advice:通知,定义在切点处执行的逻辑(@Before、@After、@Around 等)
  • Proxy:代理对象,AOP 的核心实现载体

三、反射技术在 AOP 中的关键应用

3.1 反射获取方法元信息

AOP 在扫描和匹配切点时,大量使用反射技术获取方法的元信息。

3.1.1 Method 反射获取
java 复制代码
// Spring AOP 源码中的关键反射调用
Method[] methods = targetClass.getDeclaredMethods();
for (Method method : methods) {
    // 获取方法注解
    Annotation[] annotations = method.getAnnotations();
    // 获取方法参数类型
    Class<?>[] parameterTypes = method.getParameterTypes();
    // 获取方法返回类型
    Class<?> returnType = method.getReturnType();
    // 获取方法名称
    String methodName = method.getName();
}

反射技术要点

  • getDeclaredMethods():获取类中声明的所有方法(包括私有方法)
  • getAnnotations():获取方法上的所有注解
  • getParameterTypes():获取方法参数类型数组
  • getReturnType():获取方法返回类型
3.1.2 注解反射解析
java 复制代码
// AspectJ 注解解析中的反射应用
@Aspect
public class LoggingAspect {
    @Before("execution(* com.example.service.*.*(..))")
    public void beforeMethod(JoinPoint joinPoint) {
        // 通过反射获取目标方法信息
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        Method method = signature.getMethod();
        String methodName = method.getName();
        Class<?>[] parameterTypes = method.getParameterTypes();
    }
}

反射在注解解析中的作用

  • 扫描 @Aspect 注解标记的类
  • 解析 @Before@After@Around 等通知注解
  • 提取切点表达式(execution@annotation 等)
  • 构建切点匹配器(Pointcut

3.2 反射调用目标方法

在代理对象执行时,需要通过反射调用原始目标方法。

3.2.1 JDK 动态代理中的反射调用
java 复制代码
// JDK 动态代理 InvocationHandler 实现
public class JdkDynamicAopProxy implements InvocationHandler {
    private final AdvisedSupport advised;
    
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        // 1. 通过反射获取目标对象
        Object target = getTarget();
        
        // 2. 获取方法拦截器链
        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, target.getClass());
        
        // 3. 构建方法调用对象(MethodInvocation)
        MethodInvocation invocation = new ReflectiveMethodInvocation(
            proxy, target, method, args, target.getClass(), chain);
        
        // 4. 执行拦截器链
        return invocation.proceed();
    }
}

反射关键点

  • Method.invoke(target, args):通过反射调用目标方法
  • method.getParameterTypes():获取参数类型用于方法匹配
  • method.getReturnType():获取返回类型用于返回值处理
3.2.2 CGLIB 代理中的反射调用
java 复制代码
// CGLIB MethodInterceptor 实现
public class CglibAopProxy implements MethodInterceptor {
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        // 1. 获取目标对象(通过反射)
        Object target = getTarget();
        
        // 2. 获取拦截器链
        List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, target.getClass());
        
        // 3. 构建方法调用
        CglibMethodInvocation invocation = new CglibMethodInvocation(
            proxy, target, method, args, target.getClass(), chain);
        
        // 4. 执行拦截器链
        return invocation.proceed();
    }
}

CGLIB 反射应用

  • CGLIB 通过 MethodProxy.invoke()MethodProxy.invokeSuper() 调用方法
  • 底层仍依赖反射机制获取方法元信息
  • 使用 ASM 字节码技术生成代理类,但方法调用仍需反射

3.3 反射在切点匹配中的应用

java 复制代码
// Pointcut 匹配器中的反射应用
public class AspectJExpressionPointcut implements Pointcut {
    @Override
    public boolean matches(Method method, Class<?> targetClass) {
        // 1. 通过反射获取方法签名信息
        String methodName = method.getName();
        Class<?>[] paramTypes = method.getParameterTypes();
        Class<?> returnType = method.getReturnType();
        
        // 2. 获取方法注解(反射)
        Annotation[] annotations = method.getAnnotations();
        
        // 3. 匹配切点表达式
        return pointcutExpression.matches(method, targetClass);
    }
}

四、AOP 代理对象的创建时机

4.1 BeanPostProcessor 机制

Spring AOP 的代理对象创建依赖于 BeanPostProcessor 机制,核心类是 AbstractAutoProxyCreator

4.1.1 BeanPostProcessor 执行时机
java 复制代码
// AbstractApplicationContext.refresh() 方法中的关键流程
public void refresh() throws BeansException {
    // 1. 注册 BeanPostProcessor
    registerBeanPostProcessors(beanFactory);
    
    // 2. 初始化单例 Bean
    finishBeanFactoryInitialization(beanFactory);
}

执行顺序

  1. Bean 定义加载阶段 :扫描 @Aspect 注解,注册切面 Bean
  2. BeanPostProcessor 注册阶段 :注册 AnnotationAwareAspectJAutoProxyCreator
  3. Bean 实例化阶段 :每个 Bean 创建时都会经过 BeanPostProcessor.postProcessAfterInitialization()
4.1.2 AbstractAutoProxyCreator 核心逻辑
java 复制代码
// AbstractAutoProxyCreator.postProcessAfterInitialization()
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        // 判断是否需要创建代理
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    // 1. 如果已经处理过,直接返回
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    
    // 2. 如果不需要增强,直接返回
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    
    // 3. 如果是基础设施类,不需要代理
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
    
    // 4. 获取增强器(Advisor)
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    
    // 5. 如果找到增强器,创建代理对象
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        Object proxy = createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }
    
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

关键时机点

  • Bean 初始化完成后postProcessAfterInitialization() 方法执行
  • 切面扫描完成后 :所有 @Aspect 类已注册为 Bean
  • 增强器匹配阶段getAdvicesAndAdvisorsForBean() 匹配切点

4.2 @EnableAspectJAutoProxy 注解的作用

java 复制代码
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
    boolean proxyTargetClass() default false;
    boolean exposeProxy() default false;
}

核心作用

  • 导入 AspectJAutoProxyRegistrar,注册 AnnotationAwareAspectJAutoProxyCreator Bean
  • proxyTargetClass=true:强制使用 CGLIB 代理
  • exposeProxy=true:暴露代理对象到 AopContext
4.2.1 AspectJAutoProxyRegistrar 注册逻辑
java 复制代码
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        // 注册 AnnotationAwareAspectJAutoProxyCreator
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
        
        // 解析 @EnableAspectJAutoProxy 注解属性
        AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(
            importingClassMetadata, EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy != null) {
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
    }
}

五、动态代理类生成的阶段

5.1 JDK 动态代理类生成

5.1.1 Proxy.newProxyInstance() 源码分析
java 复制代码
// java.lang.reflect.Proxy.newProxyInstance()
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) {
    // 1. 验证 InvocationHandler 非空
    Objects.requireNonNull(h);
    
    // 2. 获取代理类 Class 对象(关键:动态生成代理类)
    Class<?> cl = getProxyClass0(loader, intfs);
    
    // 3. 通过反射获取构造函数
    final Constructor<?> cons = cl.getConstructor(constructorParams);
    
    // 4. 创建代理实例
    return cons.newInstance(new Object[]{h});
}

private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) {
    // 1. 接口数量限制检查
    if (interfaces.length > 65535) {
        throw new IllegalArgumentException("interface limit exceeded");
    }
    
    // 2. 从缓存中获取或生成代理类
    return proxyClassCache.get(loader, interfaces);
}

代理类生成时机

  • 首次调用时Proxy.newProxyInstance() 首次调用时生成代理类
  • 类加载阶段 :通过 ProxyClassFactory 生成代理类的字节码
  • 缓存机制:生成的代理类会被缓存,后续直接使用
5.1.2 代理类字节码生成
java 复制代码
// ProxyClassFactory.apply() 方法(简化版)
private static final class ProxyClassFactory implements BiFunction<ClassLoader, Class<?>[], Class<?>> {
    @Override
    public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {
        // 1. 生成代理类名称:$Proxy0, $Proxy1, ...
        String proxyName = proxyPkg + proxyClassNamePrefix + num++;
        
        // 2. 生成代理类字节码
        byte[] proxyClassFile = ProxyGenerator.generateProxyClass(proxyName, interfaces, accessFlags);
        
        // 3. 通过 ClassLoader 加载代理类
        return defineClass0(loader, proxyName, proxyClassFile, 0, proxyClassFile.length);
    }
}

生成的代理类特点

  • 实现所有目标接口
  • 所有方法调用都转发给 InvocationHandler.invoke()
  • 包含 equals()hashCode()toString() 等方法的代理实现

5.2 CGLIB 代理类生成

5.2.1 Enhancer 创建代理类
java 复制代码
// CGLIB Enhancer 创建代理对象
public class CglibAopProxy implements AopProxy {
    @Override
    public Object getProxy(@Nullable ClassLoader classLoader) {
        try {
            Class<?> rootClass = this.advised.getTargetClass();
            Class<?> proxySuperClass = rootClass;
            
            // 1. 创建 Enhancer
            Enhancer enhancer = createEnhancer();
            
            // 2. 设置父类(目标类)
            enhancer.setSuperclass(proxySuperClass);
            
            // 3. 设置接口
            enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
            
            // 4. 设置回调(MethodInterceptor)
            enhancer.setCallback(new DynamicAdvisedInterceptor(this.advised));
            
            // 5. 生成代理类并创建实例
            return createProxyClassAndInstance(enhancer, callbacks);
        } catch (CodeGenerationException | IllegalArgumentException ex) {
            throw new AopConfigException("Could not generate CGLIB subclass", ex);
        }
    }
}

CGLIB 代理类生成时机

  • Bean 创建时createProxy() 方法调用时
  • 字节码生成阶段:使用 ASM 框架生成子类字节码
  • 类加载阶段 :通过 ClassLoader.defineClass() 加载生成的类
5.2.2 CGLIB 代理类特点
java 复制代码
// CGLIB 生成的代理类结构(简化)
public class UserService$$EnhancerBySpringCGLIB$$xxx extends UserService {
    private MethodInterceptor CGLIB$CALLBACK_0;
    
    @Override
    public void saveUser(User user) {
        // 调用拦截器
        MethodInterceptor interceptor = this.CGLIB$CALLBACK_0;
        if (interceptor != null) {
            interceptor.intercept(this, 
                CGLIB$saveUser$0$Method, 
                new Object[]{user}, 
                CGLIB$saveUser$0$Proxy);
        } else {
            super.saveUser(user);
        }
    }
}

CGLIB 代理特点

  • 继承目标类,重写所有非 final 方法
  • 使用 MethodInterceptor 拦截方法调用
  • 通过 MethodProxy 实现高效的方法调用

5.3 代理方式选择逻辑

java 复制代码
// DefaultAopProxyFactory.createAopProxy()
@Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    // 1. 判断是否强制使用 CGLIB
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
        Class<?> targetClass = config.getTargetClass();
        if (targetClass == null) {
            throw new AopConfigException("TargetSource cannot determine target class");
        }
        // 2. 目标类是接口,使用 JDK 代理
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        // 3. 使用 CGLIB 代理
        return new ObjenesisCglibAopProxy(config);
    } else {
        // 4. 有接口,使用 JDK 代理
        return new JdkDynamicAopProxy(config);
    }
}

选择规则

  • 有接口且未强制 CGLIB:使用 JDK 动态代理
  • 无接口或强制 CGLIB:使用 CGLIB 代理
  • 目标类是接口:使用 JDK 动态代理

六、基于 AOP 注解生命周期的完整执行流程

时序图:

markdown 复制代码
1. Spring 容器启动
   ↓
2. @EnableAspectJAutoProxy 注册 AnnotationAwareAspectJAutoProxyCreator
   ↓
3. 扫描 @Aspect 注解的类,注册为 Bean
   ↓
4. 解析切面中的通知方法,构建 Advisor 列表
   ↓
5. 目标 Bean 实例化
   ↓
6. BeanPostProcessor.postProcessAfterInitialization() 执行
   ↓
7. 匹配增强器(通过反射匹配方法)
   ↓
8. 创建代理对象(JDK 或 CGLIB)
   ↓
9. 代理对象替换原始 Bean
   ↓
10. 方法调用时,代理对象拦截
    ↓
11. 构建拦截器链
    ↓
12. 按顺序执行拦截器(@Around → @Before → 目标方法 → @AfterReturning/@AfterThrowing → @After)
    ↓
13. 通过反射调用目标方法
    ↓
14. 返回结果

6.1 阶段一:配置类扫描与注册(@EnableAspectJAutoProxy)

6.1.1 配置类加载
java 复制代码
@Configuration
@EnableAspectJAutoProxy
@ComponentScan("com.example")
public class AppConfig {
}

执行流程

  1. Spring 容器启动ApplicationContext 初始化
  2. 配置类解析ConfigurationClassPostProcessor 处理 @Configuration 注解
  3. 注解导入@EnableAspectJAutoProxy 触发 AspectJAutoProxyRegistrar 注册
6.1.2 AspectJAutoProxyCreator 注册
java 复制代码
// AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary()
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}

public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
        BeanDefinitionRegistry registry, @Nullable Object source) {
    // 注册 AnnotationAwareAspectJAutoProxyCreator
    return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

关键点

  • AnnotationAwareAspectJAutoProxyCreator 继承 AbstractAutoProxyCreator
  • 实现了 BeanPostProcessor 接口
  • 在 Bean 初始化后处理阶段创建代理对象

6.2 阶段二:切面类扫描与解析(@Aspect)

6.2.1 切面类扫描
java 复制代码
@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.example.service.*.*(..))")
    public void beforeMethod(JoinPoint joinPoint) {
        System.out.println("Before method: " + joinPoint.getSignature().getName());
    }
}

扫描流程

  1. 组件扫描@ComponentScan 扫描 @Aspect 注解的类
  2. Bean 定义注册:将切面类注册为 Spring Bean
  3. 切面解析AnnotationAwareAspectJAutoProxyCreator 解析切面信息
6.2.2 切面元数据提取
java 复制代码
// BeanFactoryAspectJAdvisorsBuilder.buildAspectJAdvisors()
public List<Advisor> buildAspectJAdvisors() {
    List<String> aspectNames = this.aspectBeanNames;
    
    if (aspectNames == null) {
        List<Advisor> advisors = new ArrayList<>();
        List<String> beanNames = new ArrayList<>();
        
        // 1. 获取所有 Bean 名称
        for (String beanName : beanNames) {
            // 2. 判断是否是切面类(通过反射检查 @Aspect 注解)
            if (isAspect(beanType)) {
                aspectNames.add(beanName);
                AspectMetadata amd = new AspectMetadata(beanType, beanName);
                
                // 3. 解析切面中的通知方法(通过反射获取方法注解)
                List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                advisors.addAll(classAdvisors);
            }
        }
        this.aspectBeanNames = aspectNames;
        return advisors;
    }
}

反射技术应用

  • Class.isAnnotationPresent(Aspect.class):检查类是否有 @Aspect 注解
  • Method.getAnnotations():获取方法上的所有注解
  • Method.getParameterTypes():解析通知方法参数类型

6.3 阶段三:增强器(Advisor)构建

6.3.1 通知方法解析
java 复制代码
// ReflectiveAspectJAdvisorFactory.getAdvisors()
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
    Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
    
    // 1. 通过反射获取所有方法
    Method[] methods = aspectClass.getDeclaredMethods();
    List<Advisor> advisors = new ArrayList<>();
    
    for (Method method : methods) {
        // 2. 解析通知注解(@Before、@After、@Around 等)
        Advisor advisor = getAdvisor(method, aspectInstanceFactory, advisors.size(), aspectName);
        if (advisor != null) {
            advisors.add(advisor);
        }
    }
    
    return advisors;
}
6.3.2 切点表达式解析
java 复制代码
// AbstractAspectJAdvisorFactory.getPointcut()
protected AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
    // 1. 通过反射获取方法上的注解
    AspectJAnnotation<?> aspectJAnnotation = AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    
    if (aspectJAnnotation == null) {
        return null;
    }
    
    // 2. 提取切点表达式
    AspectJExpressionPointcut ajexp = new AspectJExpressionPointcut(
        candidateAspectClass, new String[0], new Class<?>[0]);
    ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
    
    return ajexp;
}

反射关键操作

  • Method.getAnnotation(Before.class):获取 @Before 注解
  • Method.getAnnotation(After.class):获取 @After 注解
  • Method.getAnnotation(Around.class):获取 @Around 注解
  • 通过反射读取注解属性值(如 value()pointcut()

6.4 阶段四:目标 Bean 创建与代理对象生成

6.4.1 Bean 实例化
java 复制代码
@Service
public class UserService {
    public void saveUser(User user) {
        // 业务逻辑
    }
}

Bean 创建流程

  1. 实例化 :通过反射创建 Bean 实例(Constructor.newInstance()
  2. 属性注入:注入依赖的 Bean
  3. 初始化 :调用 @PostConstruct 方法和 InitializingBean.afterPropertiesSet()
  4. 后处理 :执行 BeanPostProcessor.postProcessAfterInitialization()
6.4.2 代理对象创建
java 复制代码
// AbstractAutoProxyCreator.wrapIfNecessary()
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    // 1. 获取匹配的增强器
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    
    // 2. 如果找到增强器,创建代理
    if (specificInterceptors != DO_NOT_PROXY) {
        this.advisedBeans.put(cacheKey, Boolean.TRUE);
        Object proxy = createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
        return proxy;
    }
    
    return bean;
}

代理创建时机

  • Bean 初始化完成后postProcessAfterInitialization() 执行
  • 增强器匹配成功 :找到匹配的 Advisor
  • 代理对象替换:返回代理对象替代原始 Bean

6.5 阶段五:方法调用与拦截器链执行

6.5.1 代理方法调用入口
java 复制代码
// JdkDynamicAopProxy.invoke()
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    Object oldProxy = null;
    boolean setProxyContext = false;
    
    TargetSource targetSource = this.advised.targetSource;
    Object target = null;
    
    try {
        // 1. 判断是否是 equals、hashCode 等基础方法
        if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
            return equals(args[0]);
        }
        if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
            return hashCode();
        }
        if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
            method.getDeclaringClass() != Advised.class) {
            // 2. 获取目标对象
            target = targetSource.getTarget();
            Class<?> targetClass = (targetClass != null ? targetClass : target.getClass());
            
            // 3. 获取拦截器链(通过反射匹配方法)
            List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
            
            // 4. 如果拦截器链为空,直接调用目标方法
            if (chain.isEmpty()) {
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
            } else {
                // 5. 构建方法调用对象,执行拦截器链
                MethodInvocation invocation = new ReflectiveMethodInvocation(
                    proxy, target, method, args, targetClass, chain);
                retVal = invocation.proceed();
            }
            
            return retVal;
        }
    } finally {
        if (target != null && !targetSource.isStatic()) {
            targetSource.releaseTarget(target);
        }
    }
}
6.5.2 拦截器链执行
java 复制代码
// ReflectiveMethodInvocation.proceed()
@Override
public Object proceed() throws Throwable {
    // 1. 如果所有拦截器都执行完毕,调用目标方法
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
        return invokeJoinpoint();
    }
    
    // 2. 获取下一个拦截器
    Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    
    // 3. 执行拦截器
    if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
        InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
        if (dm.methodMatcher.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 复制代码
// AopUtils.invokeJoinpointUsingReflection()
public static Object invokeJoinpointUsingReflection(@Nullable Object target, Method method, Object[] args) throws Throwable {
    try {
        ReflectionUtils.makeAccessible(method);
        return method.invoke(target, args);
    } catch (InvocationTargetException ex) {
        throw ex.getTargetException();
    }
}

6.6 阶段六:通知方法执行顺序

6.6.1 @Around 通知执行
java 复制代码
@Aspect
@Component
public class LoggingAspect {
    @Around("execution(* com.example.service.*.*(..))")
    public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        System.out.println("Around before");
        try {
            // 调用目标方法(通过反射)
            Object result = joinPoint.proceed();
            System.out.println("Around after returning");
            return result;
        } catch (Exception e) {
            System.out.println("Around after throwing");
            throw e;
        } finally {
            System.out.println("Around after");
        }
    }
}

执行流程

  1. @Around 前置逻辑 :执行 aroundMethod() 方法的前半部分
  2. 调用目标方法joinPoint.proceed() 触发拦截器链继续执行
  3. @Around 后置逻辑:目标方法返回后执行后半部分
6.6.2 通知执行顺序
java 复制代码
// 完整的通知执行顺序
@Aspect
@Component
public class LoggingAspect {
    @Before("execution(* com.example.service.*.*(..))")
    public void beforeMethod(JoinPoint joinPoint) {
        // 1. @Before 执行
    }
    
    @After("execution(* com.example.service.*.*(..))")
    public void afterMethod(JoinPoint joinPoint) {
        // 4. @After 执行(无论是否异常)
    }
    
    @AfterReturning("execution(* com.example.service.*.*(..))")
    public void afterReturning(JoinPoint joinPoint, Object result) {
        // 3. @AfterReturning 执行(正常返回)
    }
    
    @AfterThrowing("execution(* com.example.service.*.*(..))")
    public void afterThrowing(JoinPoint joinPoint, Exception ex) {
        // 3. @AfterThrowing 执行(异常抛出)
    }
    
    @Around("execution(* com.example.service.*.*(..))")
    public Object aroundMethod(ProceedingJoinPoint joinPoint) throws Throwable {
        // 0. @Around 前置
        try {
            Object result = joinPoint.proceed(); // 调用目标方法
            // 2. @Around 后置(正常返回)
            return result;
        } catch (Throwable e) {
            // 2. @Around 后置(异常)
            throw e;
        }
    }
}

执行顺序

  1. @Around 前置@Before目标方法@AfterReturning/@AfterThrowing@After@Around 后置
6.6.3 拦截器链构建
java 复制代码
// DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()
@Override
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
        Advised config, Method method, @Nullable Class<?> targetClass) {
    
    List<Object> interceptorList = new ArrayList<>(config.getAdvisors().length);
    Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
    
    for (Advisor advisor : config.getAdvisors()) {
        if (advisor instanceof PointcutAdvisor) {
            PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
            // 1. 通过反射匹配切点
            if (pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass) &&
                pointcutAdvisor.getPointcut().getMethodMatcher().matches(method, actualClass)) {
                
                // 2. 获取拦截器
                MethodInterceptor interceptor = (MethodInterceptor) advisor.getAdvice();
                interceptorList.add(interceptor);
            }
        }
    }
    
    return interceptorList;
}

反射匹配关键点

  • MethodMatcher.matches(method, targetClass):通过反射获取方法信息进行匹配
  • ClassFilter.matches(actualClass):通过反射检查类信息

七、AOP 底层实现的关键技术总结

7.1 反射技术的核心应用

  1. 注解扫描与解析

    • Class.getAnnotation():获取类注解
    • Method.getAnnotation():获取方法注解
    • Method.getParameterTypes():获取参数类型
  2. 方法调用

    • Method.invoke(target, args):反射调用目标方法
    • ReflectionUtils.makeAccessible():设置方法可访问
  3. 元数据获取

    • Class.getDeclaredMethods():获取类中所有方法
    • Method.getReturnType():获取返回类型
    • Method.getName():获取方法名

7.2 代理对象创建时机总结

  1. 配置阶段@EnableAspectJAutoProxy 注册 AnnotationAwareAspectJAutoProxyCreator
  2. 切面扫描阶段 :扫描 @Aspect 注解的类,构建 Advisor
  3. Bean 创建阶段 :每个 Bean 初始化完成后,通过 BeanPostProcessor 检查是否需要代理
  4. 代理生成阶段:匹配到增强器后,创建 JDK 或 CGLIB 代理对象

7.3 动态代理类生成阶段

  1. JDK 动态代理

    • 生成时机:Proxy.newProxyInstance() 调用时
    • 生成方式:ProxyGenerator.generateProxyClass() 生成字节码
    • 类加载:通过 ClassLoader.defineClass() 加载
  2. CGLIB 代理

    • 生成时机:Enhancer.create() 调用时
    • 生成方式:ASM 框架生成子类字节码
    • 类加载:通过 ClassLoader.defineClass() 加载
相关推荐
CodeAmaz4 小时前
通用 List 分批切割并循环查询数据库工具类
java·数据结构·工具类·分页
消失的旧时光-19435 小时前
Kotlinx.serialization 对多态对象(sealed class )支持更好用
java·服务器·前端
bcbnb5 小时前
如何解析iOS崩溃日志:从获取到符号化分析
后端
许泽宇的技术分享5 小时前
当AI学会“说人话“:Azure语音合成技术的魔法世界
后端·python·flask
用户69371750013845 小时前
4.Kotlin 流程控制:强大的 when 表达式:取代 Switch
android·后端·kotlin
用户69371750013845 小时前
5.Kotlin 流程控制:循环的艺术:for 循环与区间 (Range)
android·后端·kotlin
vx_bisheyuange5 小时前
基于SpringBoot的宠物商城网站的设计与实现
spring boot·后端·宠物
bcbnb5 小时前
全面解析网络抓包工具使用:Wireshark和TCPDUMP教程
后端
leonardee5 小时前
Spring Security安全框架原理与实战
java·后端
q***5185 小时前
Spring Cloud gateway 路由规则
java