美文网首页Spring
Spring5AOP——AbstractAutoProxyCre

Spring5AOP——AbstractAutoProxyCre

作者: 小波同学 | 来源:发表于2020-07-04 23:09 被阅读0次

    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<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
    
        private final Map<Object, Class<?>> proxyTypes = new ConcurrentHashMap<>(16);
    
        private final Map<Object, Boolean> 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<String> targetSourcedBeans = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
    
        private final Map<Object, Boolean> 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<Advisor> 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<Advisor> findCandidateAdvisors() {
            // Add all the Spring advisors found according to superclass rules.
            // 使用注解方式配置AOP的时候还是能够支持对XML配置的AOP的支持的.
            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;
        }
    }
    

    super.findCandidateAdvisors()

    public abstract class AbstractAdvisorAutoProxyCreator extends AbstractAutoProxyCreator {
        @Nullable
        private BeanFactoryAdvisorRetrievalHelper advisorRetrievalHelper;
    
        protected List<Advisor> 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<Advisor> 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<Advisor> 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<String> aspectBeanNames;
    
        private final Map<String, List<Advisor>> advisorsCache = new ConcurrentHashMap<>();
    
        private final Map<String, MetadataAwareAspectInstanceFactory> aspectFactoryCache = new ConcurrentHashMap<>();
    
        public List<Advisor> buildAspectJAdvisors() {
            List<String> aspectNames = this.aspectBeanNames;
    
            if (aspectNames == null) {
                synchronized (this) {
                    aspectNames = this.aspectBeanNames;
                    if (aspectNames == null) {
                        List<Advisor> 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<Advisor> 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<Advisor> advisors = new ArrayList<>();
            for (String aspectName : aspectNames) {
                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;
        }
    }
    

    this.advisorFactory.getAdvisors(factory)

    • Aspect里面的advice和pointcut被拆分成一个个的advisor。
    • advisor里的advice和pointcut是1对1的关系。
    public class ReflectiveAspectJAdvisorFactory extends AbstractAspectJAdvisorFactory implements Serializable {
    
        @Override
        public List<Advisor> 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<Advisor> 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——AbstractAutoProxyCre

        本文链接:https://www.haomeiwen.com/subject/rpzpqktx.html