08 说看过AOP相关源码,说下具体实现

vvEcho 2024-01-20 14:08:36
Categories: Tags:

Spring的aop的具体实现,在于在对象创建后为其创建代理对象,先有了原有的对象才能创建其代理;
bean 被创建后,接下来会调用所有的BeanPostProcessor 作用在 bean 上,其中有一个名叫 AnnotationAwareAspectJAutoProxyCreator(aop的核心代理创建器)的BeanPostProcessor,是它将 bean 变成了对应的代理类;

步骤如下:

  1. aop的解析与初始化
    通过 @EnableAspectJAutoProxy 注解触发 AOP 框架的初始化。该注解通过 @Import 引入 AspectJAutoProxyRegistrar,向 Spring 容器注册 AnnotationAwareAspectJAutoProxyCreator 类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // spring 核心代理类的创建器
    public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {

    }

    // BeanPostProcessor 是 Spring 扩展机制的核心接口,通过拦截 Bean 的初始化过程,允许开发者插入自定义逻辑。其典型应用包括 AOP 代理生成、属性增强等
    public interface BeanPostProcessor {
    //在 Bean 的初始化方法(如 @PostConstruct)之前执行。
    Object postProcessBeforeInitialization(Object bean, String beanName);
    //在 Bean 的初始化方法(如 @PostConstruct)之前执行。
    Object postProcessAfterInitialization(Object bean, String beanName);
    }
  2. 创建代理对象
    在 Bean 初始化完成后,AbstractAutoProxyCreator 的 postProcessAfterInitialization 方法被调用,判断是否需要为当前 Bean 创建代理

    1
    2
    3
    4
    5
    6
    // DefaultAopProxyFactory 选择代理类型
    if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
    return new JdkDynamicAopProxy(config);
    } else {
    return new ObjenesisCglibAopProxy(config);
    }

    JDK 动态代理:若目标类实现了接口,则通过 JdkDynamicAopProxy 生成代理。
    CGLIB 代理:若未实现接口或强制使用类代理(proxyTargetClass=true),则通过 CglibAopProxy 生成子类代理

  3. 扫描标注@Aspect 的类构建拦截器链
    通过 BeanFactoryAspectJAdvisorsBuilder 扫描所有标注 @Aspect 的类,解析 @Pointcut 和 @Around 等注解,生成 Advisor集合
    将 Advisor 转换为 MethodInterceptor 链,代理对象的方法调用时触发链式执行

    1
    2
    3
    4
    5
    6
    7
    // DefaultAdvisorChainFactory 构建拦截器链
    List<Object> interceptors = new ArrayList<>(advisors.length);
    for (Advisor advisor : advisors) {
    if (advisor instanceof MethodInterceptor) {
    interceptors.add((MethodInterceptor) advisor);
    }
    }
  4. 方法调用与增强逻辑执行
    方法调用被封装为 ReflectiveMethodInvocation 对象,通过 proceed() 方法依次执行拦截器链
    前置通知:在目标方法执行前调用 MethodBeforeAdvice.before()。
    后置通知:在目标方法执行后调用 AfterReturningAdvice.afterReturning()。
    环绕通知:通过 MethodInterceptor 的 invoke() 方法实现全流程控制

  5. 关键源码类与接口

    类/接口 作用
    AnnotationAwareAspectJAutoProxyCreator 代理对象创建器,解析切面并生成代理
    AbstractAutoProxyCreator 代理创建的基类,实现 Bean 后置处理逻辑
    JdkDynamicAopProxy / CglibAopProxy JDK 动态代理和 CGLIB 代理的具体实现类
    ReflectiveMethodInvocation 方法调用的核心执行逻辑,管理拦截器链
    Advisor / Advice 定义切面增强的规则和逻辑