美文网首页Spring AOP源码解读
Spring AOP DefaultAdvisorAutoPro

Spring AOP DefaultAdvisorAutoPro

作者: BugPool | 来源:发表于2020-04-08 08:26 被阅读0次

    Spring AOP源码目录

    Spring AOP源码01:Jdk动态代理底层源码
    Spring AOP源码02:ProxyFactory
    Spring AOP源码03:JdkDynamicAopProxy
    Spring AOP源码04:MethodInvocation 拦截器调用
    Spring AOP源码05:DefaultAdvisorAutoProxyCreator
    Spring期末考压轴题:当Spring AOP遇上循环依赖
    git注释源码地址:https://github.com/chaitou/spring-framework-master.git

    前言

    前面已经学习了ProxyFactory的源码,学习了如何手动硬编码使用最基础的Spring AOP,以及实现方式。这一节要学习自动代理DefaultAdvisorAutoProxyCreator源码。比起Spring AOP注解形式实现自动代理,我们之前学习的ProxyFactory还差以下2步:

    1. 代理时机:在Spring Ioc创建Bean的过程中,寻找合适的时机进行调用Spring AOP进行代理
    2. 自动代理:搜索所有bean中注解了@Aspect的类,并且提取Advisor(切面)。当一个正常的bean创建时,从这些候选的Advisor(切面)通过Pointcut寻找与之匹配的Advice,最后生成拦截器,再调用Proxy.getProxy()获取代理

    一、代理时机

    这一点应该引起大家的注意,因为很多书以及博客都没有讲明白,都是简单的一笔带过,但是笔者却认为如果连代理时机都弄不清楚,还谈什么自动代理呢?

    1. DefaultAdvisorAutoProxyCreator类图

    !](https://img.haomeiwen.com/i8190955/bc261b8789f5ad01?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
    之前的Spring Ioc源码专题的生命周期中提到过这么一段话:

    spring使用模板模式,在bean的创建过程中安插了许多锚点,用户寻找对应的锚点,通过重写方法介入到bean的创建过程当中。

    想要介入Spring Ioc创建Bean的过程,最好的方式就是实现BeanPostProcessor,想必Spring AOP也正式通过这种方式介入Bean的创建,实现自动代理的吧。可以看到DefaultAdvisorAutoProxyCreator类图最左边的分支上就实现了SmartInstantiationAwareBeanPostProcessor,在DefaultAdvisorAutoProxyCreator的父类AbstractAutoProxyCreator中,我们找到了其实现的后置方法

    AbstractAutoProxyCreator
    • postProcessBeforeInitialization 初始化前扩展
    • postProcessAfterInitialization 初始化后扩展
    • postProcessBeforeInstantiation 对象实例化前扩展
    • postProcessAfterInstantiation 对象实例化后扩展
    • postProcessPropertyValues 属性依赖注入前扩展

    5个后置处理器,只有2个有具体的实现,分别是postProcessBeforeInstantiation实例化前和postProcessAfterInitialization初始化后

    2. 源码分析

    我们从Spring Ioc创建开始跟中,在创建bean

    // AbstractAutowireCapableBeanFactory.java
    protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
             throws BeanCreationException {
    
          // 省略无关代码...
    
          try {
             // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
             /**
              * 实例化前的后置处理器
              * 给BeanPostProcessors一个机会返回代理替换调真实的实例,主要是来执行实现了InstantiationAwareBeanPostProcessor接口的BeanPostProcessor
              *
              * ① 重点:
              * AOP代理时机 1. 当用户自定义TargetSource将会在实例化前进行代理,此时的TargetSource直接返回需要被代理的Bean,也就是说该被代理的Bean的实例化初始化操作均由自己负责。并进行短路操作
              * 2. 用户不自定义TargetSource时则返回空,在初始化后才进行AOP代理
              */
             Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
             // ② 如果此时返回的bean不为空,直接短路,不再进行bean的实例化、填充、初始化!
             if (bean != null) {
                return bean;
             }
          }
          catch (Throwable ex) {
             throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
                   "BeanPostProcessor before instantiation of bean failed", ex);
          }
    
          try {
             // 核心逻辑
             Object beanInstance = doCreateBean(beanName, mbdToUse, args);
             if (logger.isTraceEnabled()) {
                logger.trace("Finished creating instance of bean '" + beanName + "'");
             }
             return beanInstance;
          }
          ...
       }
    

    ① 在bean实例化前的这个操作非常重要,之前我们在Spring Ioc时说,这边一般都返回空,但是什么时候不返回空呢?带着这个问题继续往下看源码

    ② 当不为空时,直接就return了!也就是说bean直接就不实例化、填充、初始化了!

    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
            Object bean = null;
            // 确认bean在初始化阶段之前
            if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
                // Make sure bean class is actually resolved at this point.
                if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                    // 确认当前beanName所要返回的最终类型
                    Class<?> targetType = determineTargetType(beanName, mbd);
                    if (targetType != null) {
                        // 只有前置处理返回的bean不为null, 才进行初始化后置处理(Aop的代理在初始化后置处理中进行)
                        // 但是除非bean自定义了TargetSource,否则前置处理返回的bean为空
                        // 一般没有自定义TargetSource情况下,是不会在实例化前调用该后置处理,也不会导致后续短路操作!
                        bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                        if (bean != null) {
                            // 实例化后置处理
                            bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                        }
                    }
                }
                mbd.beforeInstantiationResolved = (bean != null);
            }
            return bean;
        }
    

    前面我们提到5个后置处理器,只有2个有具体的实现,分别是postProcessBeforeInstantiation实例化前和postProcessAfterInitialization初始化后,跟上方代码已经完全对上了。接下来我们就去AbstractAutoProxyCreator中看看这2个后置处理器到底做了什么工作

    3. postProcessBeforeInstantiation

    // AbstractAutoProxyCreator.java
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
          // 省略无关代码... 
    
          /**
           * 如果我们有自定义的TargetSource,在此处创建代理。
           * TargetSource将以自定义方式处理目标实例。
           */
          // 获取自定义TargetSource
          TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
          if (targetSource != null) {
             if (StringUtils.hasLength(beanName)) {
                this.targetSourcedBeans.add(beanName);
             }
             // 获取拦截器
             Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
             // 生成代理,跟之前说过的Proxy.getProxy一样的
             Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
             // 实在缓存
             this.proxyTypes.put(cacheKey, proxy.getClass());
             // 返回代理
             return proxy;
          }
    
          return null;
       }
    

    只有targetSource != null才会返回bean,也就是说只有自定义了targetSource,从而导致后续短路操作。自定义targetSource的意思就是说我们自己负责target的创建,不需要你Spring Ioc插手。那么targetSource到底有什么用呢?例如CommonsPoolTargetSource:可以池化TargetSource,每次执行时从池中取代理对象,执行完方法再返回池中,这里不扯远

    4. postProcessAfterInitialization

        // AbstractAutoProxyCreator.java
        public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
            if (bean != null) {
                // 缓存key,一般为beanClassName_beanName
                Object cacheKey = getCacheKey(bean.getClass(), beanName);
                // bean如果有需要将会被AOP代理
                if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                    return wrapIfNecessary(bean, beanName, cacheKey);
                }
            }
            return bean;
        }
    

    5. 代理时机总结

    1. 当用户自定义了targetSource,说明代理目标target由用户自己负责窗口(包括实例化等步骤),因此在bean初始化前就会调用AbstractAutoProxyCreatorpostProcessBeforeInstantiation生成代理。生成后的代理已经是完整形态,因此,直接调用postProcessAfterInitialization对该代理进行完善,接着直接返回,进行短路操作!不需要再进行Spring Ioc创建bean的过程!
    2. 当用户没自定义targetSource时,那么这个步骤返回的便是null,则会进行Spring Ioc创建bean的标准程序,实例化、填充属性、初始化。并且在postProcessAfterInitialization中调用wrapIfNecessary进行AOP代理

    代理时机流程图:


    AOP代理时机

    二、自动代理

    上面已经说了,代理时机分为2种,但是绝大部分情况还是使用的是第二种!也就是在初始化后进行AOP代理。上面在初始化后置处理器看到AOP通过wrapIfNecessary完成

    // AbstractAutoProxyCreator.java
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
            // 该bean已经处理过了,则直接返回
            if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
                return bean;
            }
            // 无需被增强,也跳过
            if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
                return bean;
            }
            // 如果该bean是基础类,或者指定了该bean不需要代理,则不进行代理,跳过
            if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
    
            // Create proxy if we have advice.
            // 1. 获取增强拦截器
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
            // 存在增强,则进行代理
            if (specificInterceptors != DO_NOT_PROXY) {
                // 缓存表明该bean需要被增强
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
                // 2. 创建代理
                Object proxy = createProxy(
                        bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            }
            // 缓存表明bean已经增强过
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    

    1. 获取增强拦截器

        // AbstractAdvisorAutoProxyCreator.java 
        protected Object[] getAdvicesAndAdvisorsForBean(
                Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
            // 1. 获取所有Advisor 2. 在所有Advisor中挑选适用的Advisor
            List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
            if (advisors.isEmpty()) {
                return DO_NOT_PROXY;
            }
            return advisors.toArray();
        }
    
        protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
            // 获取所有Advisor
            List<Advisor> candidateAdvisors = findCandidateAdvisors();
            // 在所有Advisor中寻找适用于该bean的Advisor
            List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
            extendAdvisors(eligibleAdvisors);
            if (!eligibleAdvisors.isEmpty()) {
          // 对所有Advisor进行排序
                eligibleAdvisors = sortAdvisors(eligibleAdvisors);
            }
            return eligibleAdvisors;
        }
    

    1.1 findCandidateAdvisors

        // AnnotationAwareAspectJAutoProxyCreator.java
        protected List<Advisor> findCandidateAdvisors() {
            // Add all the Spring advisors found according to superclass rules.
            // 适用注解方式配置AOP,但是可能也还存在xml配置的AOP,因此调用父类方法加载xml中的AOP声明
            List<Advisor> advisors = super.findCandidateAdvisors();
            // Build Advisors for all AspectJ aspects in the bean factory.
            if (this.aspectJAdvisorsBuilder != null) {
                // 为所有注解了@Aspect类创建增强
                advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
            }
            return advisors;
        }
    
    // BeanFactoryAspectJAdvisorsBuilder.java
    public List<Advisor> buildAspectJAdvisors() {
            List<String> aspectNames = this.aspectBeanNames;//- 获取Aspect切面的beanName
    
            // 说明还没有缓存,需要从头遍历所有bean,找出注解了@Aspect的bean
            if (aspectNames == null) {
                synchronized (this) {
                    aspectNames = this.aspectBeanNames;
                    if (aspectNames == null) {
                        List<Advisor> advisors = new ArrayList<>();
                        aspectNames = new ArrayList<>();
                        // 通过BeanFactory,也就是Ioc容器获取所有的beanName
                        String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                                this.beanFactory, Object.class, true, false);
                        // 循环所有beanName
                        for (String beanName : beanNames) {
                            // 不合法的bean直接跳过,规则由子类定义
                            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;
                            }
                            // 该bean被Aspect注解
                            if (this.advisorFactory.isAspect(beanType)) {
                                aspectNames.add(beanName);//- 缓存被Aspect注解的beanName
                                AspectMetadata amd = new AspectMetadata(beanType, beanName);
                                /**
                                 * singleton:即切面只会有一个实例;
                                 * perthis:每个切入点表达式匹配的连接点对应的AOP对象(代理对象)都会创建一个新切面实例;
                                 * pertarget:每个切入点表达式匹配的连接点对应的目标对象都会创建一个新的切面实例
                                 */
                                if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                                    MetadataAwareAspectInstanceFactory factory =
                                            new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                                    // 解析增强方法
                                    List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                                    if (this.beanFactory.isSingleton(beanName)) {
                                        // 如果bean是单例,则直接缓存Advisor
                                        this.advisorsCache.put(beanName, classAdvisors);
                                    }
                                    else {
                                        // 不是单例的情况下,只能缓存工厂,每次都取增强都得新生产一个
                                        this.aspectFactoryCache.put(beanName, factory);
                                    }
                                    // 添加Advisor
                                    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;
        }
    

    1.2 findAdvisorsThatCanApply

        // AbstractAdvisorAutoProxyCreator.java
        protected List<Advisor> findAdvisorsThatCanApply(
                List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
    
            ProxyCreationContext.setCurrentProxiedBeanName(beanName);
            try {
                // 匹配当前bean适用的advisors,只匹配到类,只有调用时JdkDynamicAopProxy.invoke才匹配到方法
                return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
            }
            finally {
                ProxyCreationContext.setCurrentProxiedBeanName(null);
            }
        }
    
        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;
                }
                //- 处理普通bean
                if (canApply(candidate, clazz, hasIntroductions)) {
                    eligibleAdvisors.add(candidate);
                }
            }
            return eligibleAdvisors;
        }
    
        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;
                // 获取Pointcut跟targetClass做匹配
                return canApply(pca.getPointcut(), targetClass, hasIntroductions);
            }
            else {
                // It doesn't have a pointcut so we assume it applies.
                return true;
            }
        }
    

    创建代理流程图:


    在这里插入图片描述

    2. 创建代理

    创建代理我们已经详解过ProxyFactory,设置接口,设置代理目标,设置增强,最后生成代理

        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();
            // 获取当前类的相关属性
            proxyFactory.copyFrom(this);
    
            if (!proxyFactory.isProxyTargetClass()) {
                if (shouldProxyTargetClass(beanClass, beanName)) {
                    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);
            }
            // 创建代理,在之前的proxyFactory已经详解过
            return proxyFactory.getProxy(getProxyClassLoader());
        }
    

    创建代理,这个接下去就很熟悉了

        public Object getProxy(@Nullable ClassLoader classLoader) {
            return createAopProxy().getProxy(classLoader);
        }
    

    相关文章

      网友评论

        本文标题:Spring AOP DefaultAdvisorAutoPro

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