SpringAOP源碼

1. 入口

SpringAOP的使用中有這么一個注解@EnableAspectJAutoProxy,按照Spring源碼的一貫套路,進入這個注解看一下源碼。重點關(guān)注這一行。

@Import(AspectJAutoProxyRegistrar.class)

查看該類

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

    /**
     * Register, escalate, and configure the AspectJ auto proxy creator based on the value
     * of the @{@link EnableAspectJAutoProxy#proxyTargetClass()} attribute on the importing
     * {@code @Configuration} class.
     */
    @Override
    public void registerBeanDefinitions(
            AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

        // 注冊 名字internalAutoProxyCreator的 AnnotationAwareAspectJAutoProxyCreator
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

        // 獲得注解的屬性
        AnnotationAttributes enableAspectJAutoProxy =
                AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);

        //根據(jù)其中的 proxyTargetClass/exposeProxy 設(shè)置beanDefinition屬性
        if (enableAspectJAutoProxy != null) {
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }
            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
    }

}

最終會調(diào)用AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary方法,注冊一個AnnotationAwareAspectJAutoProxyCreator,該類屬于AOP的核心類。

2. 整體流程

首先我們先想下,如果讓我們自己實現(xiàn),我們需要做些什么。

  • 先查找切面
  • 對切面進行解析
  • 從切面中拿到所有的增強方法(@Befor、@After)
  • 拿到這些解析創(chuàng)建代理,如果該類實現(xiàn)了接口,就用動態(tài)代理,沒有接口就用CGLIB代理
  • 最后調(diào)用@Advise里的那些@Before、@After方法

那么順著這個思路,開始看源碼。

2.1 查找切面

現(xiàn)在我們有了AnnotationAwareAspectJAutoProxyCreator這個類,查看該類的繼承關(guān)系圖。(省略一些不必要的類)。


AOP核心類圖

首先看第一個接口,BeanPostProcessor,這個接口作為頂層接口,肯定不會被外部直接調(diào)用,所以大概率是底下的幾個具體實現(xiàn)類被調(diào)用,然后通過判斷是不是InstantiationAwareBeanPostProcessor接口的類型,再執(zhí)行相應(yīng)邏輯,帶著這個疑惑,來看源碼。

2.1.1 AnnotationConfigApplicationContext.refresh()

如果之前看過SpringIOC的源碼篇的,應(yīng)該記得,Spring最核心的就是Bean,所以如果要調(diào)用Bean的邏輯的話,肯定會在創(chuàng)建Bean之后,也就是creatBean方法以后,那么我們先看AnnotationConfigApplicationContext.refresh()這個方法。

    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            //1:準(zhǔn)備刷新上下文環(huán)境
            prepareRefresh();

            //2:獲取告訴子類初始化Bean工廠  不同工廠不同實現(xiàn)
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

            //3:對bean工廠進行填充屬性
            prepareBeanFactory(beanFactory);

            try {
                // 第四:留個子類去實現(xiàn)該接口
                postProcessBeanFactory(beanFactory);

                // 調(diào)用我們的bean工廠的后置處理器. 1. 會在此將class掃描成beanDefinition  2.bean工廠的后置處理器調(diào)用
                invokeBeanFactoryPostProcessors(beanFactory);

                // 注冊我們bean的后置處理器
                registerBeanPostProcessors(beanFactory);

                // 初始化國際化資源處理器.
                initMessageSource();

                // 創(chuàng)建事件多播器
                initApplicationEventMulticaster();

                // 這個方法同樣也是留個子類實現(xiàn)的springboot也是從這個方法進行啟動tomcat的.
                onRefresh();

                //把我們的事件監(jiān)聽器注冊到多播器上
                registerListeners();

                // 實例化我們剩余的單實例bean.
                finishBeanFactoryInitialization(beanFactory);

                // 最后容器刷新 發(fā)布刷新事件(Spring cloud也是從這里啟動的)
                finishRefresh();
            }

            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception  encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }

                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();

                // Reset 'active' flag.
                cancelRefresh(ex);

                // Propagate exception to caller.
                throw ex;
            }

            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }

2.1.2 finishBeanFactoryInitialization(beanFactory)

看finishBeanFactoryInitialization(beanFactory)這個方法。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
        // 為我們的bean工廠創(chuàng)建類型轉(zhuǎn)化器  Convert
        if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
                beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
            beanFactory.setConversionService(
                    beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
        }

        /**
         * public class MainConfig implements EmbeddedValueResolverAware{
         *
         *     public void setEmbeddedValueResolver(StringValueResolver resolver) {
                this.jdbcUrl = resolver.resolveStringValue("${ds.jdbcUrl}");
                this.classDriver = resolver.resolveStringValue("${ds.classDriver}");
              }
         }
         */
        if (!beanFactory.hasEmbeddedValueResolver()) {
            beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
        }

        // 處理關(guān)于aspectj
        String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
        for (String weaverAwareName : weaverAwareNames) {
            getBean(weaverAwareName);
        }

        // Stop using the temporary ClassLoader for type matching.
        beanFactory.setTempClassLoader(null);

        //凍結(jié)所有的 bean 定義 , 說明注冊的 bean 定義將不被修改或任何進一步的處理
        beanFactory.freezeConfiguration();

        //實例化剩余的單實例bean
        beanFactory.preInstantiateSingletons();
    }

2.1.3 beanFactory.preInstantiateSingletons()

public void preInstantiateSingletons() throws BeansException {
        if (logger.isDebugEnabled()) {
            logger.debug("Pre-instantiating singletons in " + this);
        }

        //獲取我們?nèi)萜髦兴衎ean定義的名稱
        List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

        //循環(huán)我們所有的bean定義名稱
        for (String beanName : beanNames) {
            //合并我們的bean定義,轉(zhuǎn)換為統(tǒng)一的RootBeanDefinition類型(在), 方便后續(xù)處理
            RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            /**
             * 根據(jù)bean定義判斷是不是抽象的&& 不是單例的 &&不是懶加載的
             */
            if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                //是不是工廠bean
                if (isFactoryBean(beanName)) {
                    // 是factoryBean會先生成實際的bean  &beanName 是用來獲取實際bean的
                    Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
                    if (bean instanceof FactoryBean) {
                        final FactoryBean<?> factory = (FactoryBean<?>) bean;
                        boolean isEagerInit;
                        if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
                            isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
                                            ((SmartFactoryBean<?>) factory)::isEagerInit,
                                    getAccessControlContext());
                        }
                        else {
                            isEagerInit = (factory instanceof SmartFactoryBean &&
                                    ((SmartFactoryBean<?>) factory).isEagerInit());
                        }
                        //調(diào)用真正的getBean的流程
                        if (isEagerInit) {
                            getBean(beanName);
                        }
                    }
                }
                else {//非工廠Bean 就是普通的bean
                    getBean(beanName);
                }
            }
        }

        //或有的bean的名稱 ...........到這里所有的單實例的bean已經(jīng)記載到單實例bean到緩存中
        for (String beanName : beanNames) {
            //從單例緩存池中獲取所有的對象
            Object singletonInstance = getSingleton(beanName);
            //判斷當(dāng)前的bean是否實現(xiàn)了SmartInitializingSingleton接口
            if (singletonInstance instanceof SmartInitializingSingleton) {
                final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                if (System.getSecurityManager() != null) {
                    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                        smartSingleton.afterSingletonsInstantiated();
                        return null;
                    }, getAccessControlContext());
                }
                else {
                    //觸發(fā)實例化之后的方法afterSingletonsInstantiated
                    smartSingleton.afterSingletonsInstantiated();
                }
            }
        }
    }

2.1.4 getBean(beanName)方法

    /**
     * 該方法是一個空殼方法,沒有任何的實現(xiàn)邏輯 真正的邏輯調(diào)用在doGetBean()中
     * 該接口是實現(xiàn)了BeanFactory的getBean(String name)接口
     * @param name bean的名稱 該名稱也有可能是bean的alies(別名)
     * @return 我們的單例對象
     * @throws BeansException
     */
    @Override
    public Object getBean(String name) throws BeansException {
        //真正的獲取bean的邏輯
        return doGetBean(name, null, null, false);
    }

2.1.5 doGetBean(name, null, null, false)方法

重點看該方法里的createBean方法。

2.1.6 creatBean

重點看這里

        try {
            /**
             * 第1個bean后置處理器
             * 通過bean的后置處理器來進行后置處理生成代理對象,一般情況下在此處不會生成代理對象
             * 為什么不能生成代理對象,不管是我們的jdk代理還是cglib代理都不會在此處進行代理,因為我們的
             * 真實的對象沒有生成,所以在這里不會生成代理對象,那么在這一步是我們aop和事務(wù)的關(guān)鍵,因為在這里
             * 解析我們的aop切面信息進行緩存
             */
            Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
            if (bean != null) {
                return bean;
            }
        }

2.1.7 resolveBeforeInstantiation方法

到此,找到了判斷容器中有沒有InstantiationAwareBeanPostProcessors了,那么繼續(xù)看。

    @Nullable
    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            //判斷容器中是否有InstantiationAwareBeanPostProcessors
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                //獲取當(dāng)前bean 的class對象
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    /**
                     * 后置處理器的【第一次】調(diào)用 總共有九處調(diào)用 事務(wù)在這里不會被調(diào)用,aop的才會被調(diào)用
                     * 為啥aop在這里調(diào)用了,因為在此處需要解析出對應(yīng)的切面報錯到緩存中
                     */
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    //若InstantiationAwareBeanPostProcessors后置處理器的postProcessBeforeInstantiation返回不為null

                    //說明生成了代理對象那么我們就調(diào)用
                    if (bean != null) {
                        /**
                         * 后置處理器的第二處調(diào)用,該后置處理器若被調(diào)用的話,那么第一處的處理器肯定返回的不是null
                         * InstantiationAwareBeanPostProcessors后置處理器postProcessAfterInitialization
                         */

                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }

2.1.8 applyBeanPostProcessorsBeforeInstantiation

@Nullable
    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
        /**
         * 獲取容器中的所有后置處理器
         */
        for (BeanPostProcessor bp : getBeanPostProcessors()) {
            //判斷后置處理器是不是InstantiationAwareBeanPostProcessor
            if (bp instanceof InstantiationAwareBeanPostProcessor) {
                //把我們的BeanPostProcessor強制轉(zhuǎn)為InstantiationAwareBeanPostProcessor
                InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                /**
                 * 【很重要】
                 * 我們AOP @EnableAspectJAutoProxy 為我們?nèi)萜髦袑?dǎo)入了 AnnotationAwareAspectJAutoProxyCreator
                 * 我們事務(wù)注解@EnableTransactionManagement 為我們的容器導(dǎo)入了 InfrastructureAdvisorAutoProxyCreator
                 * 都是實現(xiàn)了我們的 BeanPostProcessor接口,InstantiationAwareBeanPostProcessor,
                 * 進行后置處理解析切面
                 */
                Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                if (result != null) {
                    return result;
                }
            }
        }
        return null;
    }

2.1.9 postProcessBeforeInstantiation方法

重點看這里

            /**
             * 注意看重寫方法
             * 判斷是不是基礎(chǔ)的bean (是不是切面類、通知、切點等)
             * 判斷是不是應(yīng)該跳過 默認(rèn)false (切面解析也在其中)
             */
            if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return null;
            }

2.1.10 shouldSkip方法

終于到了AnnotationAwareAspectJAutoProxyCreator.shouldSkip方法了。

    @Override
    protected boolean shouldSkip(Class<?> beanClass, String beanName) {
        /**
         * 找到候選的Advisors(通知  前置通知、后置通知等..)
         */
        List<Advisor> candidateAdvisors = findCandidateAdvisors();
        for (Advisor advisor : candidateAdvisors) {
            // 判斷這個類的原因在于:
            // AspectJPointcutAdvisor 是xml <aop:advisor 解析的對象
            // 如果  <aop:aspect ref="beanName"> 是當(dāng)前beanName 就說明當(dāng)前bean是切面類  那就跳過。
            if (advisor instanceof AspectJPointcutAdvisor &&
                    ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
                return true;
            }
        }
        return super.shouldSkip(beanClass, beanName);
    }

2.1.11 findCandidateAdvisors()方法

    /**
     * 這里會找 兩種通知方式:
     *         Advisor代理方式 (@Transactional底層的方式)
     *         AspectJ增強方式
     * @return
     */
    @Override
    protected List<Advisor> findCandidateAdvisors() {
        // 找出xml配置的Advisor和原生接口的AOP的Advisor   找出事務(wù)相關(guān)的advisor
        List<Advisor> advisors = super.findCandidateAdvisors();
        //找出Aspect相關(guān)的信息之后封裝為一個advisor
        if (this.aspectJAdvisorsBuilder != null) {
            advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
        }
        //返回我們所有的通知
        return advisors;
    }

2.1.12 buildAspectJAdvisors方法

這里可以看到,Spring里用了緩存advisorsCache來保存通知對象。

/**
     * 去容器中獲取到所有的切面信息保存到緩存中
     * @return the list of {@link org.springframework.aop.Advisor} beans
     * @see #isEligibleBean
     */
    public List<Advisor> buildAspectJAdvisors() {
        /**
         * 用于保存切面的名稱,該地方aspectNames 是我們的類級別的緩存,用戶緩存已經(jīng)解析出來的切面信息
         */
        List<String> aspectNames = this.aspectBeanNames;
        // 緩存字段aspectNames沒有值 會在第一個單例執(zhí)行后置處理器(AnnotationAwareAspectJAutoProxyCreator注冊之后)的時候就會觸發(fā)解析切面的操作
        if (aspectNames == null) {
            // 加上同步鎖, 防止多線程同時加載Aspect
            synchronized (this) {
                aspectNames = this.aspectBeanNames;
                //做了雙重檢查加鎖
                if (aspectNames == null) {
                    // 保存所有通知的集合
                    List<Advisor> advisors = new ArrayList<>();
                    // 保存切面的名稱的集合
                    aspectNames = new ArrayList<>();
                    /**
                     * aop功能中在這里傳入的是Object.class,代表去容器中獲取到所有的組件的名稱,然后再經(jīng)過
                     * 一一的進行遍歷,這個過程是十分的消耗性能的,所以說spring會再這里加入了保存切面信息的緩存。
                     * 但是事務(wù)功能不一樣,事務(wù)模塊的功能是直接去容器中獲取Advisor類型的,選擇范圍小,且不消耗性能。所以
                     * spring在事務(wù)模塊中沒有加入緩存來保存我們的事務(wù)相關(guān)的advisor
                     */
                    String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                            this.beanFactory, Object.class, true, false);
                    //遍歷我們從IOC容器中獲取處的所有bean的名稱
                    for (String beanName : beanNames) {
                        if (!isEligibleBean(beanName)) {
                            continue;
                        }
                        //通過beanName去容器中獲取到對應(yīng)class對象
                        Class<?> beanType = this.beanFactory.getType(beanName);
                        if (beanType == null) {
                            continue;
                        }
                        //根據(jù)class對象判斷是不是切面
                        if (this.advisorFactory.isAspect(beanType)) {
                            //是切面類
                            //加入到緩存中
                            aspectNames.add(beanName);
                            //把beanName和class對象構(gòu)建成為一個AspectMetadata
                            AspectMetadata amd = new AspectMetadata(beanType, beanName);
                            if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {

                                //構(gòu)建切面注解的實例工廠
                                MetadataAwareAspectInstanceFactory factory =
                                        new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                                //真正的去獲取我們的通知對象
                                List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                                //加入到緩存中
                                if (this.beanFactory.isSingleton(beanName)) {
                                    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();
        }
        /**
         * 真正的創(chuàng)建切面的時候,我們不需要去解析了而是直接去緩存中獲取處
         */
        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;
    }

至此切面解析的全過程,分析完畢。

2.2 創(chuàng)建代理

讓我們再回到AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation方法中

@Nullable
    protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
        Object bean = null;
        if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
            //判斷容器中是否有InstantiationAwareBeanPostProcessors
            if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                //獲取當(dāng)前bean 的class對象
                Class<?> targetType = determineTargetType(beanName, mbd);
                if (targetType != null) {
                    /**
                     * 后置處理器的【第一次】調(diào)用 總共有九處調(diào)用 事務(wù)在這里不會被調(diào)用,aop的才會被調(diào)用
                     * 為啥aop在這里調(diào)用了,因為在此處需要解析出對應(yīng)的切面報錯到緩存中
                     */
                    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                    //若InstantiationAwareBeanPostProcessors后置處理器的postProcessBeforeInstantiation返回不為null

                    //說明生成了代理對象那么我們就調(diào)用
                    if (bean != null) {
                        /**
                         * 后置處理器的第二處調(diào)用,該后置處理器若被調(diào)用的話,那么第一處的處理器肯定返回的不是null
                         * InstantiationAwareBeanPostProcessors后置處理器postProcessAfterInitialization
                         */

                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                    }
                }
            }
            mbd.beforeInstantiationResolved = (bean != null);
        }
        return bean;
    }

前邊已經(jīng)分析完了后置處理器的第一次調(diào)用,完成了解析AOP切面的功能。下面來看看第二次調(diào)用。

2.2.1 applyBeanPostProcessorsAfterInitialization方法

    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
        //獲取我們?nèi)萜髦械乃械腷ean的后置處理器
        for (BeanPostProcessor processor : getBeanPostProcessors()) {
            /**
             * 在這里是后置處理器的【第九次調(diào)用】 aop和事務(wù)都會在這里生存代理對象
             *
             * 【很重要】
             * 我們AOP @EnableAspectJAutoProxy 為我們?nèi)萜髦袑?dǎo)入了 AnnotationAwareAspectJAutoProxyCreator
             * 我們事務(wù)注解@EnableTransactionManagement 為我們的容器導(dǎo)入了 InfrastructureAdvisorAutoProxyCreator
             * 都是實現(xiàn)了我們的 BeanPostProcessor接口,InstantiationAwareBeanPostProcessor,
             * 在這里實現(xiàn)的是BeanPostProcessor接口的postProcessAfterInitialization來生成我們的代理對象
             */
            Object current = processor.postProcessAfterInitialization(result, beanName);
            //若只有有一個返回null 那么直接返回原始的
            if (current == null) {
                return result;
            }
            result = current;
        }
        return result;
    }

2.2.2 AbstractAutoProxyCreator.postProcessAfterInitialization方法

/**
     * 生成aop代理
     * 在該后置方法中 我們的事務(wù)和aop的代理對象都是在這生成的
     * @param bean bean實例
     * @param beanName bean的名稱
     * @return
     * @throws BeansException
     */
    @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
        if (bean != null) {
            //獲取緩存key
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            // 之前循環(huán)依賴創(chuàng)建的動態(tài)代理 如果是現(xiàn)在的bean 就不再創(chuàng)建,,并且移除
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                // 該方法將會返回動態(tài)代理實例
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }

2.2.3 wrapIfNecessary方法

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        //已經(jīng)被處理過(解析切面時targetSourcedBeans出現(xiàn)過) 就是自己實現(xiàn)創(chuàng)建動態(tài)代理邏輯
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        }
        //不需要增強的
        if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        }
        //是不是基礎(chǔ)的bean 是不是需要跳過的 重復(fù)判斷 ( 因為循環(huán)依賴是可以改變bean的,如果把bean改成了advisor呢)
        if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }

        // 根據(jù)當(dāng)前bean找到匹配的advisor
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
        // 當(dāng)前bean匹配到了advisor
        if (specificInterceptors != DO_NOT_PROXY) {
            // 標(biāo)記為已處理
            this.advisedBeans.put(cacheKey, Boolean.TRUE);
            //創(chuàng)建我們的真正的代理對象
            Object proxy = createProxy(
                    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
            //加入到緩存
            this.proxyTypes.put(cacheKey, proxy.getClass());
            return proxy;
        }

        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }

2.2.4 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);
        }
        //創(chuàng)建一個代理對象工廠
        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);

        //為proxyFactory設(shè)置創(chuàng)建jdk代理還是cglib代理
        // 如果設(shè)置了 <aop:aspectj-autoproxy proxy-target-class="true"/>不會進if,說明強制使用cglib
        if (!proxyFactory.isProxyTargetClass()) {
            // 內(nèi)部設(shè)置的 ,   配置類就會設(shè)置這個屬性
            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }
            else {
                // 檢查有沒有接口
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }

        //把我們的specificInterceptors數(shù)組中的Advisor轉(zhuǎn)化為數(shù)組形式的
        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
        //為我們的代理工廠加入通知器,
        proxyFactory.addAdvisors(advisors);
        //設(shè)置targetSource對象
        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);
        // 代表之前是否篩選advise.
        // 因為繼承了AbstractAdvisorAutoProxyCreator , 并且之前調(diào)用了findEligibleAdvisors進行篩選, 所以是true
        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
        //真正的創(chuàng)建代理對象
        return proxyFactory.getProxy(getProxyClassLoader());
    }

2.2.5 getProxy

    public Object getProxy(@Nullable ClassLoader classLoader) {
        //createAopProxy() 用來獲取我們的代理工廠
        return createAopProxy().getProxy(classLoader);
    }

2.2.6 DefaultAopProxyFactory.createAopProxy

這個方法就是AOP創(chuàng)建代理的核心方法,有接口就用JDK動態(tài)代理,沒有接口就用CGLIB代理。

    /**
     *
     * @param config 用來為我們指定我們advisor信息
     * 該方法用來創(chuàng)建我們的代理對象
     * 所我們的targetClass對象實現(xiàn)了接口,且  ProxyTargetClass 沒有指定強制的走cglib代理,那么就是創(chuàng)建jdk代理
     * 我們代理的類沒有實現(xiàn)接口,那么會直接走cglib代理
     * 若我們   ProxyTargetClass 指定為false 且代理類是接口才會走jdk代理 否在我們還是cglib代理
     * @return
     * @throws AopConfigException
     */
    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        //判斷我們是否前置指定使用cglib代理ProxyTargetClass =true   或者沒有接口
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: " +
                        "Either an interface or a target is required for proxy creation.");
            }
            //所targetClass是接口 使用的就是jdk代理
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            //cglib代理
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            //動態(tài)代理
            return new JdkDynamicAopProxy(config);
        }
    }

至此所有代碼分析完畢。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容