spring-源码-AOP使用

说明

本文,从代码来解析AOP的一些概念、源码、流程等…

首先需要对spring AOP 的一些概念需要有一些了解…

  1. Aspect (切面)
  2. Advice(通知)
  3. Pointcut(切入点)
  4. Advisor(增强器、顾问)我比较喜欢称之为增强器,如果注释中存在增强器指的就是这个…
  5. Target (目标对象)

切面、通知、切入点

简单说,一个切面定义了 切入点通知

而 Advisor(顾问、增强器)将切面的里面的 切入点和通知进行了一个包装

在这里插入图片描述

什么时候起作用

也就说 我们的AOP 什么时候去使用的?我们知道 当一个Bean注册的时候会对Bean 做一些列操作 ,简单说也就是 相关 BeanPostProcessor,而我们通过接口分析得知AnnotationAwareAspectJAutoProxyCreator最终是实现了SmartInstantiationAwareBeanPostProcessorInstantiationAwareBeanPostProcessor也就是说基本是 执行 BeanPostProcessor的时候去进行处理的,在通过源码了解到 BeanPostProcessor 是贯穿了我们 Bean 的生命周期的,那其实我们想知道这个什么时候起的作用,只需要知道实现的这几个方法什么时候执行的即可

接口

单从结果上看 仅仅只有 AbstractAutoProxyCreator 去实现了这些方法,子类并没有重新和覆盖

SmartInstantiationAwareBeanPostProcessor

  1. predictBeanType
  2. determineCandidateConstructors
  3. getEarlyBeanReference

InstantiationAwareBeanPostProcessor

  1. postProcessBeforeInstantiation
  2. postProcessAfterInstantiation
  3. postProcessProperties
  4. postProcessPropertyValues

调用时机可参考 InstantiationAwareBeanPostProcessor

AbstractAutoProxyCreator 去实现了这些方法

BeanPostProcessor

  1. postProcessBeforeInitialization
  2. postProcessAfterInitialization

调用时机可参考 BeanPostProcessor

AbstractAutoProxyCreator去实现了这些方法

说明

当创建一个 Bean 的时候,也就说只有2个地方可能会返回代理对象,一个是直接返回代理对象,根本不给机会去创建对象,另一个是走完初始化方法调用后返回代理对象

主流程

主流程指的是DBUG线程调用的地方方法~~,也就说每一次的Bean 创建都会走这里…

  1. refresh();
  2. finishBeanFactoryInitialization(beanFactory);
  3. beanFactory.preInstantiateSingletons();
  4. getBean(beanName);
  5. doGetBean()
  6. getSingleton()
  7. createBean()

resolveBeforeInstantiation

给 BeanPostProcessors 一个 机会 返回 一个代理替换这个目标 Bean 的 实例,简单来说,直接就通过代理返回结果了

    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        // beforeInstantiationResolved 可能是 null 、true、false
        // null  代表 bean 没有走过 resolveBeforeInstantiation 这个方法
        // true  代表 bean 已经走过 resolveBeforeInstantiation 这个方法
        // false 代表 bean 不需要走 resolveBeforeInstantiation 这个方法
        // 这里是为了一个效率的存在,当如果 这个 BeanDefinition 已经走过一边后,并且返回了 false 后下次就不会继续走了
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            // 1. 判断是不是 合成 Bean
            // 2. 判断有没有 实现了 InstantiationAwareBeanPostProcessor 这个接口的  BeanPostProcessors
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    // 执行前置方法
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    // 如果不是 null 就代表已经返回对象了,则会去执行后置方法
                    if (bean != null) {
                        // 执行后置方法
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            // bean != null 返回 true 代表 bean 已经被创建
            // bean != null 返回 false 代表 bean 不需要进行代理..
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }
 

这里可以看到一个细节就是 BeanDefinition. beforeInstantiationResolved 这个属性 是为了缓存结果,简单来说当走完所有的 InstantiationAwareBeanPostProcessors 后如果都是不创建那就会定义为 false,也就是说在 多例(原型)的情况下这里的代码如果第一次走完后,下次如果是false就会直接返回.

postProcessBeforeInstantiation

在这里插入图片描述

Aspect 、Advice、Pointcut、Advisor

这里简单说就是获取增强器,可以通过XML、接口、注解方式进行配置,来让我们一步一步的将他吃透…大致是这些流程…

在这里插入图片描述

postProcessBeforeInstantiation

AbstractAutoProxyCreator.postProcessBeforeInstantiation

    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
 
        // 获取 一个用于缓存 key 其实就是 BeanName
        Object cacheKey = getCacheKey(beanClass, beanName);
 
        // 判断 targetSourcedBeans 不包含这个 bean
        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
 
            // 判断需要增强的 Bean 是否包含这个 Bean
            // advisedBeans 包含所有 切面Bean 和 增强Bean
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
 
            //1. 判断是不是 基础类型,也就说判断是不是 实现了这些接口 Advice、Pointcut、Advisor、AopInfrastructureBean、
            //2. 还会判断是不是 有没有 @Aspect 注解
            // isInfrastructureClass 执行方法,主要注意的是 this 的指向是 AnnotationAwareAspectJAutoProxyCreator,
            // 所以执行 AnnotationAwareAspectJAutoProxyCreator.isInfrastructureClass()
            // 这段逻辑是处理如果是基础类、切面类、原始类 都不会进行代理
            if (isInfrastructureClass(beanClass) ||
                    // 所以执行 AnnotationAwareAspectJAutoProxyCreator.shouldSkip()
                    // 判断是不是需要跳过,如果返回true则就会将 这个 name 进行缓存
                    shouldSkip(beanClass, beanName)) {
                // 这里其实是将 切面 Bean 的BeanName 缓存起来,代表这个 Bean 不进行 增强操作
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }
 
        // 如果我们有自定义的TargetSource,请在此处创建代理。
        // 禁止目标Bean的不必要的默认实例化: TargetSource 将以自定义方式处理目标实例。
        TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
        if (targetSource != null) {
            // 这个 BeanName 是正常的
            if (StringUtils.hasLength(beanName)) {
                this.targetSourcedBeans.add(beanName);
            }
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            //创建代理对象
            Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }
        return null;
    }

shouldSkip

isInfrastructureClass 执行方法,主要注意的是 this 的指向是 AbstractAutoProxyCreator,
所以会执行AnnotationAwareAspectJAutoProxyCreator.shouldSkip()

protected boolean shouldSkip(Class<?> beanClass, String beanName) {
 
    // 找到候选的 增强器,也就是说是切面里面的通知方法
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
 
    // 循环所有 增强器
    for (Advisor advisor : candidateAdvisors) {
 
        //判断我们的增强器是不是 AspectJPointcutAdvisor 这个类型
        if (advisor instanceof AspectJPointcutAdvisor &&
 
            // 并且 增强的名称和我们的BeanName 是一致
            ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
            return true;
        }
    }
 
    // 这里基本返回 false..
    return super.shouldSkip(beanClass, beanName);
}
 
// 父类的方法
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
    // 判断是不是  原始的实例,也就是说是不需要进行代理的实例
    return AutoProxyUtils.isOriginalInstance(beanName, beanClass);
}
 
static boolean isOriginalInstance(String beanName, Class<?> beanClass) {
 
    // 如果 BeanName 不正常 返回 false
    // beanName 的长度不是  bean全限定类名+ ORIGINAL_INSTANCE_SUFFIX(原始后缀),也返回 false
    // 也就是说这里基本会返回 false 那什么时候返回 True 呢 当我们的Bean 是全限定类名 + ORIGINAL_INSTANCE_SUFFIX 的时候...
    // 这里可以去手动注册一个 这样的Bean,演示DEMO 在下面~~~
    if (!StringUtils.hasLength(beanName) || beanName.length() !=
        beanClass.getName().length() + AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX.length()) {
        return false;
    }
    return (beanName.startsWith(beanClass.getName()) &&
            beanName.endsWith(AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX));
}
 
 
//-----------------------------DEMO
// @EnableAspectJAutoProxy
// @ComponentScan
// public class IsOriginalInstanceContext {
//     public static void main(String[] args) {
//         AnnotationConfigApplicationContext value = new AnnotationConfigApplicationContext();
//         value.register(IsOriginalInstanceContext.class);
//         value.registerBeanDefinition(IsOriginalInstanceBean.class.getName()
//                         + AutowireCapableBeanFactory.ORIGINAL_INSTANCE_SUFFIX,
//                 BeanDefinitionBuilder.genericBeanDefinition(IsOriginalInstanceBean.class).getBeanDefinition()
//         );
//         value.refresh();
//     }
// }
//----------------------------

findCandidateAdvisors(获取所有的增强器)

这里也是同理,会调用AnnotationAwareAspectJAutoProxyCreator.findCandidateAdvisors()

这里逻辑分为两步

  1. 调用父类的findCandidateAdvisors()方法获取的是 实现了 Advisor 接口的Bean
  2. 获取的是注解 切面里面所有的 Advisor
protected List<Advisor> findCandidateAdvisors() {
 
    // 获取所有  实现  Advisor 接口的类,这里的代码就不贴了.. 自己可以去看看比如自己转配一个 Bean 去实现这个 Advisor
    List<Advisor> advisors = super.findCandidateAdvisors();
 
    // Build Advisors for all AspectJ aspects in the bean factory.
    if (this.aspectJAdvisorsBuilder != null) {
        // 建立 切面增强器
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    }
    return advisors;
}

buildAspectJAdvisors

    public List<Advisor> buildAspectJAdvisors() {
        // 因为解析会很消耗性能,所以 Spring 会使用 aspectBeanNames 保存解析结果
        List<String> aspectNames = this.aspectBeanNames;
        // 如果==null 代表没处理过,因为第二次肯定不为 null,在 进入这个条件后,就会创建 ArrayList
        if (aspectNames == null) {
            // 进行加锁处理,防止多线程情况下一起操作解析
            synchronized (this) {
                // 二次赋值,防治以及操作过了
                aspectNames = this.aspectBeanNames;
                //双重非空判断,避免再次解析
                if (aspectNames == null) {
                    List<Advisor> advisors = new ArrayList<>();
                    // 创建切面集合
                    aspectNames = new ArrayList<>();
                    // 查找所有的 BeanName 包括父类
                    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                            this.beanFactory, Object.class, true, false);
                    for (String beanName : beanNames) {
 
                        //排除不合法的ban,由子类定义规则,默认返回true
                        if (!isEligibleBean(beanName)) {
                            continue;
                        }
                        // 根据Name获取Class类型
                        Class<?> beanType = this.beanFactory.getType(beanName);
                        if (beanType == null) {
                            continue;
                        }
                        // 判断 是否存在 @Aspect 注解 并且判断 目标类上所有的属性不包含 "ajc$"
                        if (this.advisorFactory.isAspect(beanType)) {
                            // 将 切面的 BeanName 放入到集合中
                            aspectNames.add(beanName);
                            // 包装成 AspectMetadata
                            AspectMetadata amd = new AspectMetadata(beanType, beanName);
                            //检查 @Aspect 注解的value值,验证生成的增强是否是单例
                            if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
 
                                // 创建一个工厂..
                                MetadataAwareAspectInstanceFactory factory =
                                        new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
 
                                // 获取标记 Aspect 注解的增强方法
                                List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                                //如果bean是单例,则缓存bean的增强器
                                if (this.beanFactory.isSingleton(beanName)) {
                                    // 将 切面 BeanName 和 增强器 进行缓存
                                    this.advisorsCache.put(beanName, classAdvisors);
                                }
                                // bean非单例,只缓存bean对应的增强器创建工厂
                                else {
                                    this.aspectFactoryCache.put(beanName, factory);
                                }
                                // 将获取的 增强器 放入到集合中
                                advisors.addAll(classAdvisors);
                            }
                            else {
                                // 切面创建模式非单例,这里的Else 基本不会进来...
                                // 如果切面是非单例,但是bean是单例,抛出异常
                                if (this.beanFactory.isSingleton(beanName)) {
                                    throw new IllegalArgumentException("Bean with name '" + beanName +
                                            "' is a singleton, but aspect instantiation model is not singleton");
                                }
                                MetadataAwareAspectInstanceFactory factory =
                                        new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
                                this.aspectFactoryCache.put(beanName, factory);
                                //获取所有切面
                                advisors.addAll(this.advisorFactory.getAdvisors(factory));
                            }
                        }
                    }
                    //将已经解析过的切面 Bean 进行缓存
                    this.aspectBeanNames = aspectNames;
                    return advisors;
                }
            }
        }
        // 如果是 null 就会直接返回...
        if (aspectNames.isEmpty()) {
            // 如果是一个空的就返回一个空集合
            return Collections.emptyList();
        }
        List<Advisor> advisors = new ArrayList<>();
        // 循环 切面的Name
        for (String aspectName : aspectNames) {
            // 根据切面的Name 获取 增强器
            List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
            if (cachedAdvisors != null) {
                advisors.addAll(cachedAdvisors);
            }
            else {
                MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
                advisors.addAll(this.advisorFactory.getAdvisors(factory));
            }
        }
        // 返回~~~~
        return advisors;
    }

getAdvisors(获取所有增强器)

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
    // 获取 切面的 Class
    Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    // 获取 切面的 Name
    String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
    // 对切面进行校验
    validate(aspectClass);
 
    // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
    // so that it will only instantiate once.
    MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
        new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
 
    List<Advisor> advisors = new ArrayList<>();
 
    // 获取 切面的所有方法,排除 @Pointcut
    for (Method method : getAdvisorMethods(aspectClass)) {
        // Prior to Spring Framework 5.2.7, advisors.size() was supplied as the declarationOrderInAspect
        // to getAdvisor(...) to represent the "current position" in the declared methods list.
        // However, since Java 7 the "current position" is not valid since the JDK no longer
        // returns declared methods in the order in which they are declared in the source code.
        // Thus, we now hard code the declarationOrderInAspect to 0 for all advice methods
        // discovered via reflection in order to support reliable advice ordering across JVM launches.
        // Specifically, a value of 0 aligns with the default value used in
        // AspectJPrecedenceComparator.getAspectDeclarationOrder(Advisor).
 
        // 尝试解析每个方法,找到方法对应的切点和通知
        Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
        if (advisor != null) {
            // 解析完后放入集合
            advisors.add(advisor);
        }
    }
 
    // 这里的分支一般不会走进..所以直接略过吧,别问,问了就是我大致略了一眼就不想看了
    if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
        Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
        advisors.add(0, instantiationAdvisor);
    }
 
 
    // 处理 @DeclareParents  注解
    for (Field field : aspectClass.getDeclaredFields()) {
        Advisor advisor = getDeclareParentsAdvisor(field);
        if (advisor != null) {
            advisors.add(advisor);
        }
    }
 
    return advisors;
}

getAdvisor(获取单个增强器)

从这里可以看出 Advisor 指的就是 切入点和通知的集合

public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
                          int declarationOrderInAspect, String aspectName) {
    // 校验...
    validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
    // 获取 切入点
    AspectJExpressionPointcut expressionPointcut = getPointcut(
        candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
    if (expressionPointcut == null) {
        return null;
    }
 
    // 在创建 InstantiationModelAwarePointcutAdvisorImpl 的时候 里面有一个 instantiateAdvice--> getAdvice 比较重要需要看一下
    // 将切入点和通知包装成一个 增强器
    return new InstantiationModelAwarePointcutAdvisorImpl(
        expressionPointcut,  //切入点表达式
        candidateAdviceMethod, //通知方法
        this,
        aspectInstanceFactory, // 切面实例的工厂..
        declarationOrderInAspect,  //0
        aspectName //切面名称
    );
}
getPointcut(获取切入点)

获取Pointcut(切入点),需要说明的是这里如果使用的 @Pointcut 定义的切入点… 并没有进行解析,简单说 AspectJExpressionPointcut 的 Pointcut 仅仅是 @Pointcut的方法名…

    @Nullable
    private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
        // 获取方法的(通知)
        // Pointcut.class,
        // Around.class,
        // Before.class,
        // After.class,
        // AfterReturning.class,
        // AfterThrowing.class
        AspectJAnnotation<?> aspectJAnnotation =
                AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
        if (aspectJAnnotation == null) {
            return null;
        }
        // 构建一个 切点
        AspectJExpressionPointcut ajexp =
                new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
        // 设置 通知表达式
        ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
        if (this.beanFactory != null) {
            ajexp.setBeanFactory(this.beanFactory);
        }
        // 返回切点
        return ajexp;
    }

1

创建InstantiationModelAwarePointcutAdvisorImpl(通知和增强器)
    public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
            Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
            MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
        // 精简代码....
        // 如果是懒加载
        if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
            // 这里不用太关注.
        }
        else {
            // A singleton aspect.
            this.pointcut = this.declaredPointcut;
            this.lazy = false;
            this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
        }
    }
 
instantiateAdvice(初始化通知)
    private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
        Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
                this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
        // 如果没有通知,则返回一个空的..
        return (advice != null ? advice : EMPTY_ADVICE);
    }
getAdvice(获取通知)
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
                        MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
    //切面类 带有@Aspect注解的类
    Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    validate(candidateAspectClass);
    // 获取方法的(通知)来确认当前方法是具体的那个类型的通知
    // Pointcut.class,
    // Around.class,
    // Before.class,
    // After.class,
    // AfterReturning.class,
    // AfterThrowing.class
    AspectJAnnotation<?> aspectJAnnotation =
        AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    if (aspectJAnnotation == null) {
        return null;
    }
 
    //再去校验一遍 如果不是切面类 则抛出异常
    if (!isAspect(candidateAspectClass)) {
        throw new AopConfigException("");
    }
 
    AbstractAspectJAdvice springAdvice;
    // 根据通知类型,创建不同的通知~~
    switch (aspectJAnnotation.getAnnotationType()) {
        case AtPointcut:
            if (logger.isDebugEnabled()) {
                logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
            }
            return null;
 
        case AtAround:
            springAdvice = new AspectJAroundAdvice(
                candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
            //如果是前置通知,则直接创建AspectJMethodBeforeAdvice实例
            //入参为:通知方法、切点表达式、切面实例
        case AtBefore:
            springAdvice = new AspectJMethodBeforeAdvice(
                candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
            //如果是后置通知,则直接创建AspectJAfterAdvice实例
            //入参为:通知方法、切点表达式、切面实例
        case AtAfter:
            springAdvice = new AspectJAfterAdvice(
                candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            break;
            //如果是后置返回通知,则直接创建AspectJAfterReturningAdvice实例
            //入参为:通知方法、切点表达式、切面实例
        case AtAfterReturning:
            springAdvice = new AspectJAfterReturningAdvice(
                candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
            //设置后置返回值的参数name
            if (StringUtils.hasText(afterReturningAnnotation.returning())) {
                springAdvice.setReturningName(afterReturningAnnotation.returning());
            }
            break;
            //如果是后置异常通知,则直接创建AspectJAfterThrowingAdvice实例
            //入参为:通知方法、切点表达式、切面实例
        case AtAfterThrowing:
            springAdvice = new AspectJAfterThrowingAdvice(
                candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
            AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
            //设置后置异常通知 异常类型参数name
            if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
                springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
            }
            break;
        default:
            throw new UnsupportedOperationException(
                "Unsupported advice type on method: " + candidateAdviceMethod);
    }
 
    // 切面的名字
    springAdvice.setAspectName(aspectName);
    springAdvice.setDeclarationOrder(declarationOrder);
    // 通知注解中的参数名,换而言之就是获取 通知注解中的 argNames 属性
    String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
    if (argNames != null) {
        springAdvice.setArgumentNamesFromStringArray(argNames);
    }
    //计算argNames和类型的对应关系
    springAdvice.calculateArgumentBindings();
    return springAdvice;
}
 

getCustomTargetSource

这个单独领出来说,是这里…想要进入条件比较刻薄

protected TargetSource getCustomTargetSource(Class<?> beanClass, String beanName) {
    // customTargetSourceCreators 不为空
    // beanFactory 不为空
    // bean  存在 spring容器中
    if (this.customTargetSourceCreators != null &&
        this.beanFactory != null && this.beanFactory.containsBean(beanName)) {
        for (TargetSourceCreator tsc : this.customTargetSourceCreators) {
            TargetSource ts = tsc.getTargetSource(beanClass, beanName);
            if (ts != null) {
                // Found a matching TargetSource.
                if (logger.isTraceEnabled()) {
                    logger.trace("TargetSourceCreator [" + tsc +
                                 "] found custom TargetSource for bean with name '" + beanName + "'");
                }
                return ts;
            }
        }
    }
 
    // No custom TargetSource found.
    return null;
}

说明

整个上面的所有代码都是获取 Aspect 和 Advice 和 Pointcut

  1. 缓存了 实现了 Advisor 接口 Bean 的name
  2. 缓存了 @Aspect 注解的 Bean 的name
  3. 缓存了 切面 Bean 下面的所有 Advisor(Advice、Pointcut)

为什么这么做… 为了效率,因为每一次都会去拦截,每次都会去走一遍,对其数据进行缓存,其实随处可见的细节太多了…

处理Weaving、Joinpoint、Proxy、Target

根据主流程~~ 继续DBUG,也就是说没有直接返回代理对象~~这里的代码就不贴了,直接贴核心代码

  1. doCreateBean
  2. initializeBean
  3. applyBeanPostProcessorsAfterInitialization

分析 postProcessAfterInitialization

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    // 判断这个对象是否创建成功..
    if (bean != null) {
        // 获取一个 key ,用于缓存..
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            // 这里就是去搞代理去了
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}

wrapIfNecessary(包装目标类,如果需要的话)

这里的细节点是 可以看到 advisedBeans.put(cacheKye,Boolean.FALSE) 或者ture ,其实为了就是效率…

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
 
    // 判断 beanName是正常的 并且 targetSourcedBeans 已经存在则会直接返回
    if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    //判断 Bean 是不是 不需要增强,如果不需要直接返回
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    //判断 是不是 切面 这里上面已经分析过了....
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        // 如果是 切面 放入到集合当中,
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
 
    // Create proxy if we have advice.
    // 创建代理对象
    // 1. 获取当前Bean 的所有增强器(通知方法)
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    // 如果不是 null 则会去生成代理对象,否则则标记当前类不需要进行代理.
    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;
    }
    // 如果不需要代理则设置为 False 当下次进来的时候会直接返回(细节)
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
}

getAdvicesAndAdvisorsForBean

protected Object[] getAdvicesAndAdvisorsForBean(
    Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
    //获取这个类型的所有增强器
    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    // 如果是一个空的 则返回 一个空的 数组
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    // 将其转换成数组返回
    return advisors.toArray();
}

findEligibleAdvisors(找到合适的增强器)

    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
        //获取所有的增强器,这里之前已经分析过了就不分析了..
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        //找到适合的增强器
        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        extendAdvisors(eligibleAdvisors);
        if (!eligibleAdvisors.isEmpty()) {
            // 对增强器进行 排序
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }
        return eligibleAdvisors;
    }

findAdvisorsThatCanApply(找到能够应用的增强器)

protected List<Advisor> findAdvisorsThatCanApply(
    List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
 
    ProxyCreationContext.setCurrentProxiedBeanName(beanName);
    try {
        // 返回当前Bean能用的增强器
        return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
    }
    finally {
        ProxyCreationContext.setCurrentProxiedBeanName(null);
    }
}

findAdvisorsThatCanApply(找到能够应用的增强器)

    public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
        // 如果是空..就直接返回..
        if (candidateAdvisors.isEmpty()) {
            return candidateAdvisors;
        }
        //存放 合格的 增强器
        List<Advisor> eligibleAdvisors = new ArrayList<>();
        //循环所有的增强器
        for (Advisor candidate : candidateAdvisors) {
                //判断类型是不是整个类型的
            if (candidate instanceof IntroductionAdvisor
                // 去应用..
                && canApply(candidate, clazz)) {
                eligibleAdvisors.add(candidate);
            }
        }
        boolean hasIntroductions = !eligibleAdvisors.isEmpty();
        // 循环所有的增强器
        for (Advisor candidate : candidateAdvisors) {
            //判断如果是这个类型的就跳过,因为上个循环已经处理过了
            if (candidate instanceof IntroductionAdvisor) {
                // already processed
                continue;
            }
            // 判断是不是能用的增强器,如果是能用的则添加到集合当中去
            if (canApply(candidate, clazz, hasIntroductions)) {
                eligibleAdvisors.add(candidate);
            }
        }
        return eligibleAdvisors;
    }
 

canApply(能够应用的增强器)

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
    // 判断 是不是这个类型的
    if (advisor instanceof IntroductionAdvisor) {
        return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
    }
    // 判断 是不是这个类型的
    else if (advisor instanceof PointcutAdvisor) {
        PointcutAdvisor pca = (PointcutAdvisor) advisor;
        // 判断切入点表达式是否匹配
        return canApply(pca.getPointcut(), targetClass, hasIntroductions);
    }
    else {
        // 它没有切入点,因此我们假设它适用。
        return true;
    }
}

canApply(能够应用的增强器)

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
    Assert.notNull(pc, "Pointcut must not be null");
    //  这一步会去解析 切入点表达式...
    if (!pc.getClassFilter().matches(targetClass)) {
        return false;
    }
 
    MethodMatcher methodMatcher = pc.getMethodMatcher();
    if (methodMatcher == MethodMatcher.TRUE) {
        // No need to iterate the methods if we're matching any method anyway...
        return true;
    }
 
    IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
    if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
        introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
    }
 
    Set<Class<?>> classes = new LinkedHashSet<>();
    // 判断是否是 Proxy 的子类并且 proxyClassCache 存在 这个类
    if (!Proxy.isProxyClass(targetClass)) {
        classes.add(ClassUtils.getUserClass(targetClass));
    }
    // 返回当前类的所实现的所有的接口..
    classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
 
    for (Class<?> clazz : classes) {
        // 获取当前类上包括父类的所有方法
        Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
        // 循环所有方法
        for (Method method : methods) {
            if (introductionAwareMethodMatcher != null ?
                introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
                methodMatcher.matches(method, targetClass)) {
                return true;
            }
        }
    }
 
    return false;
}

getClassFilter(获取切点表达式)

解析切入点表达式…为过滤做准备

public ClassFilter getClassFilter() {
    obtainPointcutExpression();
    return this;
}
obtainPointcutExpression(获取切入点表达式)
private PointcutExpression obtainPointcutExpression() {
    // 如果表达式不存在 抛出异常...
    if (getExpression() == null) {
        throw new IllegalStateException("Must set property 'expression' before attempting to match");
    }
    // 如果 切入点表达式 是null 去进行解析,因为我们的表达式可能是 通过@Pointcut 的方式
    if (this.pointcutExpression == null) {
        this.pointcutClassLoader = determinePointcutClassLoader();
        this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader);
    }
    return this.pointcutExpression;
}
 
buildPointcutExpression

去解析表达式…

    private PointcutExpression buildPointcutExpression(@Nullable ClassLoader classLoader) {
         // 初始化基础的Aspect切入点解析器
        PointcutParser parser = initializePointcutParser(classLoader);
        // 获取切入点参数...
        PointcutParameter[] pointcutParameters = new PointcutParameter[this.pointcutParameterNames.length];
        for (int i = 0; i < pointcutParameters.length; i++) {
            // 将参数和类型包装一下 放入到数组中
            pointcutParameters[i] = parser.createPointcutParameter(
                    this.pointcutParameterNames[i], this.pointcutParameterTypes[i]);
        }
        // 这里嵌套了3个方法....而且还异常复杂我都不忍心看...
        return parser.parsePointcutExpression(replaceBooleanOperators(resolveExpression()),
                this.pointcutDeclarationScope, pointcutParameters);
    }
resolveExpression
private String resolveExpression() {
    // 获取表达式
    String expression = getExpression();
    Assert.state(expression != null, "No expression set");
    // 返回表达式
    return expression;
}
replaceBooleanOperators
private String replaceBooleanOperators(String pcExpr) {
    // 将表达式中的 and 替换
    String result = StringUtils.replace(pcExpr, " and ", " && ");
    // 将表达式中的 or 替换
    result = StringUtils.replace(result, " or ", " || ");
    // 将表达式中的 not 替换
    result = StringUtils.replace(result, " not ", " ! ");
    return result;
}
parsePointcutExpression
public PointcutExpression parsePointcutExpression(String expression, Class<?> inScope, PointcutParameter[] formalParameters)
    throws UnsupportedPointcutPrimitiveException, IllegalArgumentException {
    PointcutExpressionImpl pcExpr = null;
    try {
        // 这里是对表达式的进行处理,具体的可以自己深究去
        Pointcut pc = resolvePointcutExpression(expression, inScope, formalParameters);
        // 将表达式具体化,比如我使用的是 @Before("方法()") 这里是去将 "方法()" 转换成具体的 表达式
        pc = concretizePointcutExpression(pc, inScope, formalParameters);
        // again, because we have now followed any ref'd pcuts
        validateAgainstSupportedPrimitives(pc, expression);
        // 包装成 对象返回
        pcExpr = new PointcutExpressionImpl(pc, expression, formalParameters, getWorld());
    } catch (ParserException pEx) {
        throw new IllegalArgumentException(buildUserMessageFromParserException(expression, pEx));
    } catch (ReflectionWorld.ReflectionWorldException rwEx) {
        throw new IllegalArgumentException(rwEx.getMessage());
    }
    return pcExpr;
}

matches(匹配当前类)

public boolean matches(Class<?> targetClass) {
    // 这里是去获取 切入点表达式.. 也包括了解析(这里其实在 getClassFilter) 已经解析过了~~
    PointcutExpression pointcutExpression = obtainPointcutExpression();
    try {
        try {
            //根据表达式的解析实例,验证此类是否匹配
            return pointcutExpression.couldMatchJoinPointsInType(targetClass);
        }
        catch (ReflectionWorldException ex) {
            logger.debug("PointcutExpression matching rejected target class - trying fallback expression", ex);
            // Actually this is still a "maybe" - treat the pointcut as dynamic if we don't know enough yet
            PointcutExpression fallbackExpression = getFallbackPointcutExpression(targetClass);
            if (fallbackExpression != null) {
                return fallbackExpression.couldMatchJoinPointsInType(targetClass);
            }
        }
    }
    catch (Throwable ex) {
        logger.debug("PointcutExpression matching rejected target class", ex);
    }
    return false;
}
couldMatchJoinPointsInType(判断当前类是否可以匹配切入点)

这里仅仅是去匹配当前类是否符合规则

public boolean couldMatchJoinPointsInType(Class aClass) {
    ResolvedType matchType = world.resolve(aClass.getName());
    if (matchType.isMissing() && (world instanceof ReflectionWorld)) {
        // Class is a generated class that cannot be 'looked up' via getResource.
        // For example a proxy or lambda.
        // Use the class itself in this case
        matchType = ((ReflectionWorld)world).resolveUsingClass(aClass);
    }
    ReflectionFastMatchInfo info = new ReflectionFastMatchInfo(matchType, null, this.matchContext, world);
    //根据切入点和 目标类,判断类 package 是否匹配
    boolean couldMatch = pointcut.fastMatch(info).maybeTrue();
    return couldMatch;
}

说明

上面一大串代码都是为了去进行匹配,当匹配成功的时候才会去创建代理对象

createProxy

创建代理对象

protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
                             @Nullable Object[] specificInterceptors, TargetSource targetSource) {

    if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
        AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
    }
    //创建 代理工厂
    ProxyFactory proxyFactory = new ProxyFactory();
    // 将当前类的一些配置进行 复制 ,简单来说就是获取 XML 或者注解配置的属性..
    // 这里可以参考一下:
    proxyFactory.copyFrom(this);
    // 判断是否是通过接口 默认是 False
    if (!proxyFactory.isProxyTargetClass()) {
        //根据最开始@EnableAspectJAutoProxy注解中的proxyTargetClass参数判断是否应该使用cglib代理
        if (shouldProxyTargetClass(beanClass, beanName)) {
            //标识 使用cglib动态代理
            proxyFactory.setProxyTargetClass(true);
        } else {
            evaluateProxyInterfaces(beanClass, proxyFactory);
        }
    }
    // 获取到增强器
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    // 放入到 代理工厂
    proxyFactory.addAdvisors(advisors);
    // 设置 目标 对象
    proxyFactory.setTargetSource(targetSource);
    // 留个子类去实现的一个方法,也就是说我们可以通过重写这个方法进行定制
    customizeProxyFactory(proxyFactory);

    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
        proxyFactory.setPreFiltered(true);
    }

    return proxyFactory.getProxy(getProxyClassLoader());
}

getProxy

public Object getProxy(@Nullable ClassLoader classLoader) {
    // createAopProxy() 获取AOP 工厂判断 CGlib还是JDK
    return createAopProxy().getProxy(classLoader);
}

createAopProxy

protected final synchronized AopProxy createAopProxy() {
    if (!this.active) {
        activate();
    }
    // 获取到 AOP 代理工厂
    // 然后判断 是 Cglib 还是JDK
    return getAopProxyFactory().createAopProxy(this);
}

createAopProxy

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {

    if (!IN_NATIVE_IMAGE &&
        (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
        //  optimize  默认是 false
        //  ProxyTargetClass 默认是 false
        //  hasNoUserSuppliedProxyInterfaces 被代理的类没有实现接口

        // 获取目标 Class
        Class<?> targetClass = config.getTargetClass();
        // 判断当前类是不是接口
        if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
            return new JdkDynamicAopProxy(config);
        }
        return new ObjenesisCglibAopProxy(config);
    }
    else {
        return new JdkDynamicAopProxy(config);
    }
}

getProxy

取决于 createAopProxy 返回的是 CGlib 还是JDK 代理

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值