Spring5AOP——AbstractAutoProxyCreator横切逻辑的加载与解析

Spring AOP的总体流程

  • 1、注册解析AOP的服务
  • 2、解析和加载横切逻辑
  • 3、将横切逻辑织入目标Bean中

AnnotationAwareAspectJAutoProxyCreator继承体系图

  • AnnotationAwareAspectJAutoProxyCreator既实现了SmartInstantiationAwareBeanPostProcessor 又实现了BeanFactoryAware。就可以对容器做一些事情。

  • AnnotationAwareAspectJAutoProxyCreator 实现了Order接口,所以先于普通的BeanPostProcessor注册,并对普通BeanPostProcessor也能起作用。

  • AnnotationAwareAspectJAutoProxyCreator 是InstantiationAwareBeanPostProcessor,会在Bean被创建之前,在resolveBeforeInstantiation中被调用。

  • Spring Aop主要是通过AbstractAutoProxyCreator实现的BeanPostProcessor、InstantiationAwareBeanPostProcessor以及SmartInstantiationAwareBeanPostProcessor接口里面的后置处理器方法,来介入到Spring IOC容器的Bean的实例化以及初始化的过程中对Bean进行AOP的处理的。

  • 所以AbstractAutoProxyCreator类里面的实现的容器级别的后置处理器方法便是介入分析的点,而横切逻辑的加载主要是在AbstractAutoProxyCreator类中的的postProcessBeforeInstantiation方法中,该方法是在Bean的实例化之前被调用的。

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
        implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

    //当在实例化前置方法 postProcessBeforeInstantiation 中创建了代理类,
    // 则在 targetSourcedBeans 中将添加 beanName,
    // 也就是 targetSourcedBeans 中含有 beanName
    // 则说明这个类被动态代理了
    private final Set targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));

    private final Map> proxyTypes = new ConcurrentHashMap<>(16);

    private final Map advisedBeans = new ConcurrentHashMap<>(256);

    /**
     * 在创建Bean的流程中还没调用构造器来实例化Bean的时候进行调用(实例化前后)
     * AOP解析切面以及事务解析事务注解都是在这里完成的
     * @param beanClass the class of the bean to be instantiated
     * @param beanName the name of the bean
     * @return
     */
    @Override
    public Object postProcessBeforeInstantiation(Class beanClass, String beanName) {
        //获取BeanClass的缓存key
        Object cacheKey = getCacheKey(beanClass, beanName);

        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
            //advisedBeans保存了所有已经做过动态代理的Bean
            // 如果被解析过则直接返回
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            // 1. 判断当前bean是否是基础类型:是否实现了Advice,Pointcut,Advisor,AopInfrastructureBean这些接口或是否是切面(@Aspect注解)
            // 2. 判断是不是应该跳过 (AOP解析直接解析出我们的切面信息,
            // 而事务在这里是不会解析的)
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }

        // Create proxy here if we have a custom TargetSource.
        // Suppresses unnecessary default instantiation of the target bean:
        // The TargetSource will handle target instances in a custom fashion.
        //获取用户自定义的targetSource, 如果存在则直接在对象实例化之前进行代理创建,
        // 避免了目标对象不必要的实例化
        TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
        //如果有自定义targetSource就要这里创建代理对象
        //这样做的好处是被代理的对象可以动态改变,而不是值针对一个target对象(可以对对象池中对象进行代理,可以每次创建代理都创建新对象
        if (targetSource != null) {
            if (StringUtils.hasLength(beanName)) {
                this.targetSourcedBeans.add(beanName);
            }
            //获取Advisors, 这个是交给子类实现的
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
            Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
            this.proxyTypes.put(cacheKey, proxy.getClass());
            //返回代理的对象
            return proxy;
        }

        return null;
    }
}

AbstractAutoProxyCreator的postProcessBeforeInstantiation方法是在AbstractAutowireCapableBeanFactory类中的createBean方法中的创建Bean实例方法doCreateBean方法的前一步方法resolveBeforeInstantiation方法中被最终调用的。

resolveBeforeInstantiation

  • 实例化前的处理,给InstantiationAwareBeanPostProcessor一个机会返回代理对象来替代真正的bean实例。
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        implements AutowireCapableBeanFactory {

    @Nullable
    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            // Make sure bean class is actually resolved at this point.
            //1.mbd不是合成的,并且BeanFactory中存在InstantiationAwareBeanPostProcessor
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                //2.解析beanName对应的Bean实例的类型
                Class targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    //3.实例化前的后置处理器应用(处理InstantiationAwareBeanPostProcessor)
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    if (bean != null) {
                        //4.如果返回的bean不为空,会跳过Spring默认的实例化过程
                        //所以只能在这里调用BeanPostProcessor实现类的PostProcessorsAfterInitialization方法
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            //5.如果bean不为空,则将beforeInstantiationResolved赋值为true,代表在实例化之前已经解析
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }

    @Nullable
    protected Object applyBeanPostProcessorsBeforeInstantiation(Class beanClass, String beanName) {
        //1.遍历当前BeanFactory中的BeanPostProcessor
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            //2.应用InstantiationAwareBeanPostProcessor后置处理器,允许PostProcessorBeforeInstantiation方法返回bean对象的代理
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                //3.执行postProcessBeforeInstantiation方法,在Bean实例化前操作,
                //该方法可以返回一个构造完成的Bean实例,从而不会继续执行创建Bean实例的"正规流程"
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if (result != null) {
                    //4.如果result不为null,也就是有后置处理器返回了bean实例对象,则会跳过Spring默认的实例化过程。
                    return result;
                }
            }
        }
        return null;
    }
}

因为AbstractAutoProxyCreator实现了InstantiationAwareBeanPostProcessor接口,所以,resolveBeforeInstantiation方法中的applyBeanPostProcessorsBeforeInstantiation方法中的代码ibp.postProcessBeforeInstantiation(beanClass, beanName)方法最终调用的是AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法完成的AOP相关横切逻辑的加载与解析的。

TargetSource

postProcessBeforeInstantiation方法中出现了TargetSource。

TargetSource(目标源)是被代理的target(目标对象)实例的来源。TargetSource被用于获取当前MethodInvocation(方法调用)所需要的target(目标对象),这个target通过反射的方式被调用(如:method.invode(target,args))。换句话说,proxy(代理对象)代理的不是target,而是TargetSource,这点非常重要!!!

通常情况下,一个proxy(代理对象)只能代理一个target,每次方法调用的目标也是唯一固定的target。但是,如果让proxy代理TargetSource,可以使得每次方法调用的target实例都不同(当然也可以相同,这取决于TargetSource实现)。这种机制使得方法调用变得灵活,可以扩展出很多高级功能,如:target pool(目标对象池)、hot swap(运行时目标对象热替换),等等。

public interface TargetSource extends TargetClassAware {

    /**
     * 返回当前目标源的目标类型
     * 可以返回null值,如:EmptyTargetSource(未知类会使用这个目标源)
     */
    @Override
    @Nullable
    Class getTargetClass();

    /**
     * 当前目标源是否是静态的。
     * 如果为false,则每次方法调用结束后会调用releaseTarget()释放目标对象.
     * 如果为true,则目标对象不可变,也就没必要释放了。
     */
    boolean isStatic();

    /**
     * 获取一个目标对象。
     * 在每次MethodInvocation方法调用执行之前获取。
     */
    @Nullable
    Object getTarget() throws Exception;

    /**
     * 释放指定的目标对象。
     */
    void releaseTarget(Object target) throws Exception;

}
详细的TargetSource:

Spring5AOP——TargetSource

getCustomTargetSource

  • 获取用户自定义的targetSource,如果存在则直接在对象实例化之前进行代理创建,避免了目标对象不必要的实例化。
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
        implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

    @Nullable
    protected TargetSource getCustomTargetSource(Class beanClass, String beanName) {
        // We can't create fancy target sources for directly registered singletons.
        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;
    }
}
  • 如果获取到用户自定义的targetSource实例,那么就要会走后续的创建AOP的动态代理的流程。
  • 成功创建代理之后,就将代理的类型放入到proxyTypes缓存中,便于后续的获取,之后将代理实例返回。
  • 这就就完成了AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法的执行。

到这里AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法的下半部分就攻克了,现在回到上半部分。

!this.targetSourcedBeans.contains(beanName)

回到AbstractAutoProxyCreator类中的postProcessBeforeInstantiation方法中,如果此时传入的beanName没有出现在用户自定义的targetSourcedBeans缓存列表里面,则会进入到下面方法里面。

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
        implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {

    //当在实例化前置方法 postProcessBeforeInstantiation 中创建了代理类,
    // 则在 targetSourcedBeans 中将添加 beanName,
    // 也就是 targetSourcedBeans 中含有 beanName
    // 则说明这个类被动态代理了
    private final Set targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));

    private final Map advisedBeans = new ConcurrentHashMap<>(256);

    /**
     * 在创建Bean的流程中还没调用构造器来实例化Bean的时候进行调用(实例化前后)
     * AOP解析切面以及事务解析事务注解都是在这里完成的
     * @param beanClass the class of the bean to be instantiated
     * @param beanName the name of the bean
     * @return
     */
    @Override
    public Object postProcessBeforeInstantiation(Class beanClass, String beanName) {
        //获取BeanClass的缓存key
        Object cacheKey = getCacheKey(beanClass, beanName);

        if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
            //advisedBeans保存了所有已经做过动态代理的Bean
            // 如果被解析过则直接返回
            if (this.advisedBeans.containsKey(cacheKey)) {
                return null;
            }
            // 1. 判断当前bean是否是基础类型:是否实现了Advice,Pointcut,Advisor,AopInfrastructureBean这些接口或是否是切面(@Aspect注解)
            // 2. 判断是不是应该跳过 (AOP解析直接解析出我们的切面信息,
            // 而事务在这里是不会解析的)
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }
        }
        
        ......

        return null;
    }
}

isInfrastructureClass(beanClass)

  • 判断当前bean是否是基础类型:是否实现了Advice,Pointcut,Advisor,AopInfrastructureBean这些接口或是否是切面(@Aspect注解)
public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {

    @Override
    protected boolean isInfrastructureClass(Class beanClass) {

        return (super.isInfrastructureClass(beanClass) ||
                (this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
    }
}

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
        implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    protected boolean isInfrastructureClass(Class beanClass) {
        boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
                Pointcut.class.isAssignableFrom(beanClass) ||
                Advisor.class.isAssignableFrom(beanClass) ||
                AopInfrastructureBean.class.isAssignableFrom(beanClass);
        if (retVal && logger.isTraceEnabled()) {
            logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
        }
        return retVal;
    }
}

如果beanClass是Spring AOP的基础服务类的话,将对应于该Bean的cacheKey作为key添加到advisedBeans里面,并且将其对应的值设置为false,以标识这个是已经处理过的不需要包装的Spring AOP基础服务Bean。

shouldSkip(beanClass, beanName)

  • 判断是不是应该跳过 (AOP解析直接解析出我们的切面信息,而事务在这里是不会解析的)
public class AspectJAwareAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {

    @Override
    protected boolean shouldSkip(Class beanClass, String beanName) {
        // TODO: Consider optimization by caching the list of the aspect names
        //找到候选的Advisors
        List candidateAdvisors = findCandidateAdvisors();
        for (Advisor advisor : candidateAdvisors) {
            if (advisor instanceof AspectJPointcutAdvisor &&
                    ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
                return true;
            }
        }
        return super.shouldSkip(beanClass, beanName);
    }
}

findCandidateAdvisors()

public class AnnotationAwareAspectJAutoProxyCreator extends AspectJAwareAdvisorAutoProxyCreator {

    @Override
    protected List findCandidateAdvisors() {
        // Add all the Spring advisors found according to superclass rules.
        // 使用注解方式配置AOP的时候还是能够支持对XML配置的AOP的支持的.
        List advisors = super.findCandidateAdvisors();
        // Build Advisors for all AspectJ aspects in the bean factory.
        if (this.aspectJAdvisorsBuilder != null) {
            advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        }
        return advisors;
    }
}

super.findCandidateAdvisors()

public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
    @Nullable
    private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;

    protected List findCandidateAdvisors() {
        Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
        return this.advisorRetrievalHelper.findAdvisorBeans();
    }
}

this.advisorRetrievalHelper.findAdvisorBeans()

  • 获取容器里面的AdvisorBean
public class BeanFactoryAdvisorRetrievalHelper {

    private final ConfigurableListableBeanFactory beanFactory;

    @Nullable
    private volatile String[] cachedAdvisorBeanNames;

    public List findAdvisorBeans() {
        // Determine list of advisor bean names, if not cached already.
        // 先尝试从缓存中获取容器中所有 Advisor bean 的名称
        String[] advisorNames = this.cachedAdvisorBeanNames;
        if (advisorNames == null) {
            // Do not initialize FactoryBeans here: We need to leave all regular beans
            // uninitialized to let the auto-proxy creator apply to them!
            // 如果缓存为空,尝试从容器以及其父容器分析得到所有 Advisor bean 的名称
            advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                    this.beanFactory, Advisor.class, true, false);
            // 添加进缓存
            this.cachedAdvisorBeanNames = advisorNames;
        }
        if (advisorNames.length == 0) {
            return new ArrayList<>();
        }

        List advisors = new ArrayList<>();
        for (String name : advisorNames) {
            if (isEligibleBean(name)) {
                // 创建中的 bean 会被忽略
                if (this.beanFactory.isCurrentlyInCreation(name)) {
                    if (logger.isTraceEnabled()) {
                        logger.trace("Skipping currently created advisor '" + name + "'");
                    }
                }
                else {
                    try {
                        advisors.add(this.beanFactory.getBean(name, Advisor.class));
                    }
                    catch (BeanCreationException ex) {
                        Throwable rootCause = ex.getMostSpecificCause();
                        if (rootCause instanceof BeanCurrentlyInCreationException) {
                            BeanCreationException bce = (BeanCreationException) rootCause;
                            String bceBeanName = bce.getBeanName();
                            if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
                                if (logger.isTraceEnabled()) {
                                    logger.trace("Skipping advisor '" + name +
                                            "' with dependency on currently created bean: " + ex.getMessage());
                                }
                                // Ignore: indicates a reference back to the bean we're trying to advise.
                                // We want to find advisors other than the currently created bean itself.
                                continue;
                            }
                        }
                        throw ex;
                    }
                }
            }
        }
        return advisors;
    }
}

this.aspectJAdvisorsBuilder.buildAspectJAdvisors()

  • 以注解的形式尝试从容器加载注解形式的Advisors
aspectJAdvisorsBuilder.buildAspectJAdvisors()方法主要作用
  • 从容器中获取所有的bean
  • 遍历beanName,解析出被@Aspect标记的类
  • 提取Aspect类里的Advisors
  • 将提取的结果加入缓存
public class BeanFactoryAspectJAdvisorsBuilder {

    private final ListableBeanFactory beanFactory;

    private final AspectJAdvisorFactory advisorFactory;

    @Nullable
    private volatile List aspectBeanNames;

    private final Map> advisorsCache = new ConcurrentHashMap<>();

    private final Map aspectFactoryCache = new ConcurrentHashMap<>();

    public List buildAspectJAdvisors() {
        List aspectNames = this.aspectBeanNames;

        if (aspectNames == null) {
            synchronized (this) {
                aspectNames = this.aspectBeanNames;
                if (aspectNames == null) {
                    List advisors = new ArrayList<>();
                    //用于保存切面的名称的集合
                    aspectNames = new ArrayList<>();
                    //获取所有的beanName
                    // AOP功能中在这里传入的是Object对象,代表去容器中获取到所有的组件的名称,然后再
                    // 进行遍历,这个过程是十分的消耗性能的,所以说Spring会再这里加入了保存切面信息的缓存。
                    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                            this.beanFactory, Object.class, true, false);
                    //遍历我们从IOC容器中获取处的所有Bean的名称
                    for (String beanName : beanNames) {
                        if (!isEligibleBean(beanName)) {
                            continue;
                        }
                        // We must be careful not to instantiate beans eagerly as in this case they
                        // would be cached by the Spring container but would not have been weaved.
                        //获取对应的bean的类型
                        Class beanType = this.beanFactory.getType(beanName);
                        if (beanType == null) {
                            continue;
                        }
                        //提取@Aspect注解标记的Class
                        if (this.advisorFactory.isAspect(beanType)) {
                            //是切面类
                            //加入到缓存中
                            aspectNames.add(beanName);
                            AspectMetadata amd = new AspectMetadata(beanType, beanName);
                            if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                                MetadataAwareAspectInstanceFactory factory =
                                        new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                                //Aspect里面的advice和pointcut被拆分成一个个的advisor,
                                // advisor里的advice和pointcut是1对1的关系
                                List classAdvisors = this.advisorFactory.getAdvisors(factory);
                                if (this.beanFactory.isSingleton(beanName)) {
                                    //单例则直接将Advisor类存到缓存
                                    this.advisorsCache.put(beanName, classAdvisors);
                                }
                                else {
                                    // 否则将其对应的工厂缓存
                                    this.aspectFactoryCache.put(beanName, factory);
                                }
                                advisors.addAll(classAdvisors);
                            }
                            else {
                                // Per target or per this.
                                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));
                            }
                        }
                    }
                    this.aspectBeanNames = aspectNames;
                    return advisors;
                }
            }
        }

        if (aspectNames.isEmpty()) {
            return Collections.emptyList();
        }
        List advisors = new ArrayList<>();
        for (String aspectName : aspectNames) {
            List 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;
    }
}

this.advisorFactory.getAdvisors(factory)

  • Aspect里面的advice和pointcut被拆分成一个个的advisor。
  • advisor里的advice和pointcut是1对1的关系。
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {

    @Override
    public List getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
        //获取Aspect的类Class
        Class aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
        //获取Aspect的类名
        String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
        //校验切面类
        validate(aspectClass);

        // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
        // so that it will only instantiate once.
        //我们使用的是包装模式来包装我们的MetadataAwareAspectInstanceFactory
        // 构建为MetadataAwareAspectInstanceFactory
        MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
                new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

        List advisors = new ArrayList<>();
        //获取到切面类中的所有方法,但是该方法不会解析到标注了@PointCut注解的方法
        for (Method method : getAdvisorMethods(aspectClass)) {
            //循环解析切面中的方法
            Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
            if (advisor != null) {
                advisors.add(advisor);
            }
        }

        // If it's a per target aspect, emit the dummy instantiating aspect.
        if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
            Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
            advisors.add(0, instantiationAdvisor);
        }

        // Find introduction fields.
        // 处理Introduction相关的Advice
        for (Field field : aspectClass.getDeclaredFields()) {
            Advisor advisor = getDeclareParentsAdvisor(field);
            if (advisor != null) {
                advisors.add(advisor);
            }
        }

        return advisors;
    }
}

getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);

  • 获取到切面类中的所有方法,但是该方法不会解析到标注了@PointCut注解的方法。
  • 循环解析切面中的方法。
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {

    @Override
    @Nullable
    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;
        }
        //实例化我们的切面Advisor对象
        return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
                this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
    }
}

getPointcut()

  • 切面的方法上构建切点表达式
public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {

    @Nullable
    private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class candidateAspectClass) {
        //找到Advice注解标签,并解析注解标签里面的pointCut属性值存储在AspectJAnnotation里
        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;
    }
}

new InstantiationModelAwarePointcutAdvisorImpl()

  • 实例化我们的切面Advisor对象
final class InstantiationModelAwarePointcutAdvisorImpl
        implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation, Serializable {

    public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
            Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
            MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
        //当前的Pointcut表达式
        this.declaredPointcut = declaredPointcut;
        //切面的class对象
        this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
        //切面方法的名称
        this.methodName = aspectJAdviceMethod.getName();
        //切面方法的参数类型
        this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
        //切面方法对象
        this.aspectJAdviceMethod = aspectJAdviceMethod;
        //aspectj的Advisor工厂
        this.aspectJAdvisorFactory = aspectJAdvisorFactory;
        //aspect的实例工厂
        this.aspectInstanceFactory = aspectInstanceFactory;
        //切面的顺序
        this.declarationOrder = declarationOrder;
        //切面的名称
        this.aspectName = aspectName;
        //判断当前的切面对象是否需要延时加载
        if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
            // Static part of the pointcut is a lazy type.
            Pointcut preInstantiationPointcut = Pointcuts.union(
                    aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);

            // Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
            // If it's not a dynamic pointcut, it may be optimized out
            // by the Spring AOP infrastructure after the first evaluation.
            this.pointcut = new PerTargetInstantiationModelPointcut(
                    this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
            this.lazy = true;
        }
        else {
            // A singleton aspect.
            this.pointcut = this.declaredPointcut;
            this.lazy = false;
            //将切面中的通知构造为advice通知对象
            this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
        }
    }
}

instantiateAdvice(this.declaredPointcut)

  • 将切面中的通知构造为advice通知对象
final class InstantiationModelAwarePointcutAdvisorImpl
        implements InstantiationModelAwarePointcutAdvisor, AspectJPrecedenceInformation, Serializable {

    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);
    }

}


public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {

    @Override
    @Nullable
    public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
            MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
        //获取我们的切面类的class对象
        Class candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
        validate(candidateAspectClass);
        //获取切面方法上的注解
        AspectJAnnotation aspectJAnnotation =
                AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
        if (aspectJAnnotation == null) {
            return null;
        }

        // If we get here, we know we have an AspectJ method.
        // Check that it's an AspectJ-annotated class
        //判断是否是注解切面对象
        if (!isAspect(candidateAspectClass)) {
            throw new AopConfigException("Advice must be declared inside an aspect type: " +
                    "Offending method '" + candidateAdviceMethod + "' in class [" +
                    candidateAspectClass.getName() + "]");
        }

        if (logger.isDebugEnabled()) {
            logger.debug("Found AspectJ method: " + candidateAdviceMethod);
        }

        AbstractAspectJAdvice springAdvice;
        //判断标注在方法上的注解类型
        switch (aspectJAnnotation.getAnnotationType()) {
            //是PointCut注解 那么就抛出异常 因为在外面传递进来的方法已经排除了Pointcut的方法
            case AtPointcut:
                if (logger.isDebugEnabled()) {
                    logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
                }
                return null;
            //环绕通知 构建AspectJAroundAdvice
            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();
                if (StringUtils.hasText(afterReturningAnnotation.returning())) {
                    springAdvice.setReturningName(afterReturningAnnotation.returning());
                }
                break;
            //异常通知   AspectJAfterThrowingAdvice
            case AtAfterThrowing:
                springAdvice = new AspectJAfterThrowingAdvice(
                        candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
                AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
                if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
                    springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
                }
                break;
            default:
                throw new UnsupportedOperationException(
                        "Unsupported advice type on method: " + candidateAdviceMethod);
        }

        // Now to configure the advice...
        //设置我们构建出来的通知对象的相关属性比如DeclarationOrder,
        // 在代理调用的时候,责任链顺序上会用
        springAdvice.setAspectName(aspectName);
        springAdvice.setDeclarationOrder(declarationOrder);
        String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
        if (argNames != null) {
            springAdvice.setArgumentNamesFromStringArray(argNames);
        }
        springAdvice.calculateArgumentBindings();

        return springAdvice;
    }
}

至此,就完成了Spring AOP横切逻辑的加载与解析。

参考:
https://segmentfault.com/a/1190000015830477

https://www.cnblogs.com/foreveravalon/p/8653832.html

https://www.cnblogs.com/qinzj/p/11415057.html

你可能感兴趣的:(Spring5AOP——AbstractAutoProxyCreator横切逻辑的加载与解析)