美文网首页
SpringAOP源码

SpringAOP源码

作者: 逍遥白亦 | 来源:发表于2021-03-22 22:24 被阅读0次

    1. 入口

    SpringAOP的使用中有这么一个注解@EnableAspectJAutoProxy,按照Spring源码的一贯套路,进入这个注解看一下源码。重点关注这一行。

    @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);
    
            //根据其中的 proxyTargetClass/exposeProxy 设置beanDefinition属性
            if (enableAspectJAutoProxy != null) {
                if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                    AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
                }
                if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                    AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
                }
            }
        }
    
    }
    

    最终会调用AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary方法,注册一个AnnotationAwareAspectJAutoProxyCreator,该类属于AOP的核心类。

    2. 整体流程

    首先我们先想下,如果让我们自己实现,我们需要做些什么。

    • 先查找切面
    • 对切面进行解析
    • 从切面中拿到所有的增强方法(@Befor、@After)
    • 拿到这些解析创建代理,如果该类实现了接口,就用动态代理,没有接口就用CGLIB代理
    • 最后调用@Advise里的那些@Before、@After方法

    那么顺着这个思路,开始看源码。

    2.1 查找切面

    现在我们有了AnnotationAwareAspectJAutoProxyCreator这个类,查看该类的继承关系图。(省略一些不必要的类)。


    AOP核心类图

    首先看第一个接口,BeanPostProcessor,这个接口作为顶层接口,肯定不会被外部直接调用,所以大概率是底下的几个具体实现类被调用,然后通过判断是不是InstantiationAwareBeanPostProcessor接口的类型,再执行相应逻辑,带着这个疑惑,来看源码。

    2.1.1 AnnotationConfigApplicationContext.refresh()

    如果之前看过SpringIOC的源码篇的,应该记得,Spring最核心的就是Bean,所以如果要调用Bean的逻辑的话,肯定会在创建Bean之后,也就是creatBean方法以后,那么我们先看AnnotationConfigApplicationContext.refresh()这个方法。

        @Override
        public void refresh() throws BeansException, IllegalStateException {
            synchronized (this.startupShutdownMonitor) {
                //1:准备刷新上下文环境
                prepareRefresh();
    
                //2:获取告诉子类初始化Bean工厂  不同工厂不同实现
                ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
                //3:对bean工厂进行填充属性
                prepareBeanFactory(beanFactory);
    
                try {
                    // 第四:留个子类去实现该接口
                    postProcessBeanFactory(beanFactory);
    
                    // 调用我们的bean工厂的后置处理器. 1. 会在此将class扫描成beanDefinition  2.bean工厂的后置处理器调用
                    invokeBeanFactoryPostProcessors(beanFactory);
    
                    // 注册我们bean的后置处理器
                    registerBeanPostProcessors(beanFactory);
    
                    // 初始化国际化资源处理器.
                    initMessageSource();
    
                    // 创建事件多播器
                    initApplicationEventMulticaster();
    
                    // 这个方法同样也是留个子类实现的springboot也是从这个方法进行启动tomcat的.
                    onRefresh();
    
                    //把我们的事件监听器注册到多播器上
                    registerListeners();
    
                    // 实例化我们剩余的单实例bean.
                    finishBeanFactoryInitialization(beanFactory);
    
                    // 最后容器刷新 发布刷新事件(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工厂创建类型转化器  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));
            }
    
            // 处理关于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);
    
            //冻结所有的 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);
            }
    
            //获取我们容器中所有bean定义的名称
            List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
    
            //循环我们所有的bean定义名称
            for (String beanName : beanNames) {
                //合并我们的bean定义,转换为统一的RootBeanDefinition类型(在), 方便后续处理
                RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
                /**
                 * 根据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());
                            }
                            //调用真正的getBean的流程
                            if (isEagerInit) {
                                getBean(beanName);
                            }
                        }
                    }
                    else {//非工厂Bean 就是普通的bean
                        getBean(beanName);
                    }
                }
            }
    
            //或有的bean的名称 ...........到这里所有的单实例的bean已经记载到单实例bean到缓存中
            for (String beanName : beanNames) {
                //从单例缓存池中获取所有的对象
                Object singletonInstance = getSingleton(beanName);
                //判断当前的bean是否实现了SmartInitializingSingleton接口
                if (singletonInstance instanceof SmartInitializingSingleton) {
                    final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
                    if (System.getSecurityManager() != null) {
                        AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                            smartSingleton.afterSingletonsInstantiated();
                            return null;
                        }, getAccessControlContext());
                    }
                    else {
                        //触发实例化之后的方法afterSingletonsInstantiated
                        smartSingleton.afterSingletonsInstantiated();
                    }
                }
            }
        }
    

    2.1.4 getBean(beanName)方法

        /**
         * 该方法是一个空壳方法,没有任何的实现逻辑 真正的逻辑调用在doGetBean()中
         * 该接口是实现了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和事务的关键,因为在这里
                 * 解析我们的aop切面信息进行缓存
                 */
                Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
                if (bean != null) {
                    return bean;
                }
            }
    

    2.1.7 resolveBeforeInstantiation方法

    到此,找到了判断容器中有没有InstantiationAwareBeanPostProcessors了,那么继续看。

        @Nullable
        protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
            Object bean = null;
            if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
                //判断容器中是否有InstantiationAwareBeanPostProcessors
                if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                    //获取当前bean 的class对象
                    Class<?> targetType = determineTargetType(beanName, mbd);
                    if (targetType != null) {
                        /**
                         * 后置处理器的【第一次】调用 总共有九处调用 事务在这里不会被调用,aop的才会被调用
                         * 为啥aop在这里调用了,因为在此处需要解析出对应的切面报错到缓存中
                         */
                        bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                        //若InstantiationAwareBeanPostProcessors后置处理器的postProcessBeforeInstantiation返回不为null
    
                        //说明生成了代理对象那么我们就调用
                        if (bean != null) {
                            /**
                             * 后置处理器的第二处调用,该后置处理器若被调用的话,那么第一处的处理器肯定返回的不是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强制转为InstantiationAwareBeanPostProcessor
                    InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
                    /**
                     * 【很重要】
                     * 我们AOP @EnableAspectJAutoProxy 为我们容器中导入了 AnnotationAwareAspectJAutoProxyCreator
                     * 我们事务注解@EnableTransactionManagement 为我们的容器导入了 InfrastructureAdvisorAutoProxyCreator
                     * 都是实现了我们的 BeanPostProcessor接口,InstantiationAwareBeanPostProcessor,
                     * 进行后置处理解析切面
                     */
                    Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
                    if (result != null) {
                        return result;
                    }
                }
            }
            return null;
        }
    

    2.1.9 postProcessBeforeInstantiation方法

    重点看这里

                /**
                 * 注意看重写方法
                 * 判断是不是基础的bean (是不是切面类、通知、切点等)
                 * 判断是不是应该跳过 默认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"> 是当前beanName 就说明当前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   找出事务相关的advisor
            List<Advisor> advisors = super.findCandidateAdvisors();
            //找出Aspect相关的信息之后封装为一个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 是我们的类级别的缓存,用户缓存已经解析出来的切面信息
             */
            List<String> aspectNames = this.aspectBeanNames;
            // 缓存字段aspectNames没有值 会在第一个单例执行后置处理器(AnnotationAwareAspectJAutoProxyCreator注册之后)的时候就会触发解析切面的操作
            if (aspectNames == null) {
                // 加上同步锁, 防止多线程同时加载Aspect
                synchronized (this) {
                    aspectNames = this.aspectBeanNames;
                    //做了双重检查加锁
                    if (aspectNames == null) {
                        // 保存所有通知的集合
                        List<Advisor> advisors = new ArrayList<>();
                        // 保存切面的名称的集合
                        aspectNames = new ArrayList<>();
                        /**
                         * aop功能中在这里传入的是Object.class,代表去容器中获取到所有的组件的名称,然后再经过
                         * 一一的进行遍历,这个过程是十分的消耗性能的,所以说spring会再这里加入了保存切面信息的缓存。
                         * 但是事务功能不一样,事务模块的功能是直接去容器中获取Advisor类型的,选择范围小,且不消耗性能。所以
                         * spring在事务模块中没有加入缓存来保存我们的事务相关的advisor
                         */
                        String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                                this.beanFactory, Object.class, true, false);
                        //遍历我们从IOC容器中获取处的所有bean的名称
                        for (String beanName : beanNames) {
                            if (!isEligibleBean(beanName)) {
                                continue;
                            }
                            //通过beanName去容器中获取到对应class对象
                            Class<?> beanType = this.beanFactory.getType(beanName);
                            if (beanType == null) {
                                continue;
                            }
                            //根据class对象判断是不是切面
                            if (this.advisorFactory.isAspect(beanType)) {
                                //是切面类
                                //加入到缓存中
                                aspectNames.add(beanName);
                                //把beanName和class对象构建成为一个AspectMetadata
                                AspectMetadata amd = new AspectMetadata(beanType, beanName);
                                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)) {
                                        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;
        }
    

    至此切面解析的全过程,分析完毕。

    2.2 创建代理

    让我们再回到AbstractAutowireCapableBeanFactory.resolveBeforeInstantiation方法中

    @Nullable
        protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
            Object bean = null;
            if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
                //判断容器中是否有InstantiationAwareBeanPostProcessors
                if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
                    //获取当前bean 的class对象
                    Class<?> targetType = determineTargetType(beanName, mbd);
                    if (targetType != null) {
                        /**
                         * 后置处理器的【第一次】调用 总共有九处调用 事务在这里不会被调用,aop的才会被调用
                         * 为啥aop在这里调用了,因为在此处需要解析出对应的切面报错到缓存中
                         */
                        bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
                        //若InstantiationAwareBeanPostProcessors后置处理器的postProcessBeforeInstantiation返回不为null
    
                        //说明生成了代理对象那么我们就调用
                        if (bean != null) {
                            /**
                             * 后置处理器的第二处调用,该后置处理器若被调用的话,那么第一处的处理器肯定返回的不是null
                             * InstantiationAwareBeanPostProcessors后置处理器postProcessAfterInitialization
                             */
    
                            bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                        }
                    }
                }
                mbd.beforeInstantiationResolved = (bean != null);
            }
            return bean;
        }
    

    前边已经分析完了后置处理器的第一次调用,完成了解析AOP切面的功能。下面来看看第二次调用。

    2.2.1 applyBeanPostProcessorsAfterInitialization方法

        @Override
        public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
                throws BeansException {
    
            Object result = existingBean;
            //获取我们容器中的所有的bean的后置处理器
            for (BeanPostProcessor processor : getBeanPostProcessors()) {
                /**
                 * 在这里是后置处理器的【第九次调用】 aop和事务都会在这里生存代理对象
                 *
                 * 【很重要】
                 * 我们AOP @EnableAspectJAutoProxy 为我们容器中导入了 AnnotationAwareAspectJAutoProxyCreator
                 * 我们事务注解@EnableTransactionManagement 为我们的容器导入了 InfrastructureAdvisorAutoProxyCreator
                 * 都是实现了我们的 BeanPostProcessor接口,InstantiationAwareBeanPostProcessor,
                 * 在这里实现的是BeanPostProcessor接口的postProcessAfterInitialization来生成我们的代理对象
                 */
                Object current = processor.postProcessAfterInitialization(result, beanName);
                //若只有有一个返回null 那么直接返回原始的
                if (current == null) {
                    return result;
                }
                result = current;
            }
            return result;
        }
    

    2.2.2 AbstractAutoProxyCreator.postProcessAfterInitialization方法

    /**
         * 生成aop代理
         * 在该后置方法中 我们的事务和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);
                // 之前循环依赖创建的动态代理 如果是现在的bean 就不再创建,,并且移除
                if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                    // 该方法将会返回动态代理实例
                    return wrapIfNecessary(bean, beanName, cacheKey);
                }
            }
            return bean;
        }
    

    2.2.3 wrapIfNecessary方法

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
            //已经被处理过(解析切面时targetSourcedBeans出现过) 就是自己实现创建动态代理逻辑
            if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
                return bean;
            }
            //不需要增强的
            if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
                return bean;
            }
            //是不是基础的bean 是不是需要跳过的 重复判断 ( 因为循环依赖是可以改变bean的,如果把bean改成了advisor呢)
            if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
    
            // 根据当前bean找到匹配的advisor
            Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
            // 当前bean匹配到了advisor
            if (specificInterceptors != DO_NOT_PROXY) {
                // 标记为已处理
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
                //创建我们的真正的代理对象
                Object proxy = createProxy(
                        bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                //加入到缓存
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            }
    
            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);
            }
            //创建一个代理对象工厂
            ProxyFactory proxyFactory = new ProxyFactory();
            proxyFactory.copyFrom(this);
    
            //为proxyFactory设置创建jdk代理还是cglib代理
            // 如果设置了 <aop:aspectj-autoproxy proxy-target-class="true"/>不会进if,说明强制使用cglib
            if (!proxyFactory.isProxyTargetClass()) {
                // 内部设置的 ,   配置类就会设置这个属性
                if (shouldProxyTargetClass(beanClass, beanName)) {
                    proxyFactory.setProxyTargetClass(true);
                }
                else {
                    // 检查有没有接口
                    evaluateProxyInterfaces(beanClass, proxyFactory);
                }
            }
    
            //把我们的specificInterceptors数组中的Advisor转化为数组形式的
            Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
            //为我们的代理工厂加入通知器,
            proxyFactory.addAdvisors(advisors);
            //设置targetSource对象
            proxyFactory.setTargetSource(targetSource);
            customizeProxyFactory(proxyFactory);
    
            proxyFactory.setFrozen(this.freezeProxy);
            // 代表之前是否筛选advise.
            // 因为继承了AbstractAdvisorAutoProxyCreator , 并且之前调用了findEligibleAdvisors进行筛选, 所以是true
            if (advisorsPreFiltered()) {
                proxyFactory.setPreFiltered(true);
            }
            //真正的创建代理对象
            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创建代理的核心方法,有接口就用JDK动态代理,没有接口就用CGLIB代理。

        /**
         *
         * @param config 用来为我们指定我们advisor信息
         * 该方法用来创建我们的代理对象
         * 所我们的targetClass对象实现了接口,且  ProxyTargetClass 没有指定强制的走cglib代理,那么就是创建jdk代理
         * 我们代理的类没有实现接口,那么会直接走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 {
                //动态代理
                return new JdkDynamicAopProxy(config);
            }
        }
    

    至此所有代码分析完毕。

    相关文章

      网友评论

          本文标题:SpringAOP源码

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