SpringAOP源码

2021-03-22  本文已影响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. 整体流程

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

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

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

至此所有代码分析完毕。

上一篇下一篇

猜你喜欢

热点阅读