SpringAOP之@EnableAspectJAutoProxy注解如何实现自动代理?

前面我们主要说了关于SpringAOP底层的API,这篇文章就来说说这些底层的API与SpringIOC容器的结合是如何实现对象的自动代理的

 @EnableAspectJAutoProxy

通常我们在一个spring项目中要使用SpringAOP的功能的时候,除了要加上AOP和AspectJ的依赖,还要在配置类上面加上@EnableAspectJAutoProxy注解,该注解的作用就是开启SpringAOP的自动代理功能,下面我们来看这个注解的作用

@EnableAspectJAutoProxy注解是一个组合注解,里面是一个@Import注解,往容器中import了一个AspectJAutoProxyRegistrar,这个类继承于ImportBeanDefinitionRegistrar接口,所以会来到registerBeanDefinitions方法,最终来到org.springframework.aop.config.AopConfigUtils#registerOrEscalateApcAsRequired

private static BeanDefinition registerOrEscalateApcAsRequired(
      Class<?> cls, BeanDefinitionRegistry registry, @Nullable Object source) {

   Assert.notNull(registry, "BeanDefinitionRegistry must not be null");

   if (registry.containsBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME)) {
      BeanDefinition apcDefinition = registry.getBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME);
      if (!cls.getName().equals(apcDefinition.getBeanClassName())) {
         int currentPriority = findPriorityForClass(apcDefinition.getBeanClassName());
         int requiredPriority = findPriorityForClass(cls);
         if (currentPriority < requiredPriority) {
            apcDefinition.setBeanClassName(cls.getName());
         }
      }
      return null;
   }

   RootBeanDefinition beanDefinition = new RootBeanDefinition(cls);
   beanDefinition.setSource(source);
   beanDefinition.getPropertyValues().add("order", Ordered.HIGHEST_PRECEDENCE);
   beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
   registry.registerBeanDefinition(AUTO_PROXY_CREATOR_BEAN_NAME, beanDefinition);
   return beanDefinition;
}

上面的代码就不多说了,之前也有说过,它里面所做的就是根据优先级往容器导入了AnnotationAwareAspectJAutoProxyCreator这个组件

AnnotationAwareAspectJAutoProxyCreator

先看下这个类的类关系继承图

 可以看到这个类的父类AbstractAutoProxyCreator实现了BeanPostProcessor接口,所以我们看下AbstractAutoProxyCreator这个父类

创建代理对象前置工作

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessBeforeInstantiation

根据我们对SpringIOC的bean的生命周期可以知道,这个方法是在bean实例化之前执行的

@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
   //获取cacheKey,如果该类是一个FactoryBean,那么就返回&+beanName
   Object cacheKey = getCacheKey(beanClass, beanName);

   if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
      //如果已经处理过则直接返回null
      if (this.advisedBeans.containsKey(cacheKey)) {
         return null;
      }
      //isInfrastructureClass方法主要判断该类是否是一个基础类
      //例如是Advice,Pointcut,Advisor,AopInfrastructureBean这些基础类就返回true,并且标记为已经处理不需要代理的类
      //对于AnnotationAwareAspectJAutoProxyCreator来说它重写了这个isInfrastructureClass方法
      //增强了判断包括Aspect切面类也不需要被代理
      //shouldSkip这个方法就稍微复杂点了
      //对于AbstractAutoProxyCreator父类实现是判断是否是original instance
      //子类AspectJAwareAdvisorAutoProxyCreator重写了此方法
      if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
         //如果满足上面两种条件之一,则标记为已处理的不需要代理的bean
         this.advisedBeans.put(cacheKey, Boolean.FALSE);
         return null;
      }
   }

   // Create proxy here if we have a custom TargetSource.
   // Suppresses unnecessary default instantiation of the target bean:
   // The TargetSource will handle target instances in a custom fashion.
   TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
   if (targetSource != null) {
      if (StringUtils.hasLength(beanName)) {
         this.targetSourcedBeans.add(beanName);
      }
      Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
      Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   }

   return null;
}

上面的shouldSkip方法比较复杂,我们分别来看一下该父类和子类对此方法的实现

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#shouldSkip

protected boolean shouldSkip(Class<?> beanClass, String beanName) {
   return AutoProxyUtils.isOriginalInstance(beanName, beanClass);
}

org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip

protected boolean shouldSkip(Class<?> beanClass, String beanName) {
   // TODO: Consider optimization by caching the list of the aspect names
   //找到所有的candidate advisor
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   for (Advisor advisor : candidateAdvisors) {
      if (advisor instanceof AspectJPointcutAdvisor &&
            ((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
         return true;
      }
   }
   //调用AbstractAutoProxyCreator父类的shouldSkip方法
   return super.shouldSkip(beanClass, beanName);
}

可以看出AspectJAwareAdvisorAutoProxyCreator的shouldSkip方法在父类的基础上增强了一段逻辑,这段代码逻辑就是找到所有的candidate advisor(候选的advisor),这里重点看如何找到这些candidate advisor。AnnotationAwareAspectJAutoProxyCreator重写了findCandidateAdvisors方法

org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors

@Override
protected List<Advisor> findCandidateAdvisors() {
   // Add all the Spring advisors found according to superclass rules.
   //调用父类的findCandidateAdvisors方法,这里具体是调AbstractAutoProxyCreator这个父类
   //这里寻找candidate advisor主要从两个途径去寻找
   //第一个就是调用父类的实现,第二个就是AnnotationAwareAspectJAutoProxyCreator自己的实现
   //两种途径找到的advisor就是最终要的candidate advisor
   List<Advisor> advisors = super.findCandidateAdvisors();
   // Build Advisors for all AspectJ aspects in the bean factory.
   if (this.aspectJAdvisorsBuilder != null) {
       //第二种途径寻找advisor
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   }
   return advisors;
}

我们先来看第一种寻找advisor的途径,也就是父类AbstractAdvisorAutoProxyCreator的实现

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findCandidateAdvisors

protected List<Advisor> findCandidateAdvisors() {
   Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
   return this.advisorRetrievalHelper.findAdvisorBeans();
}

这里使用了advisorRetrievalHelper这个advisor检索辅助类去寻找advisor,这个辅助类哪里来的?继续看

//由于实现了BeanFactoryAware接口,所以会回调setBeanFactory方法
public void setBeanFactory(BeanFactory beanFactory) {
   super.setBeanFactory(beanFactory);
   if (!(beanFactory instanceof ConfigurableListableBeanFactory)) {
      throw new IllegalArgumentException(
            "AdvisorAutoProxyCreator requires a ConfigurableListableBeanFactory: " + beanFactory);
   }
   initBeanFactory((ConfigurableListableBeanFactory) beanFactory);
}

protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
    //实例化了BeanFactoryAdvisorRetrievalHelperAdapter这个advisor检索辅助类
    //这个辅助类是AbstractAdvisorAutoProxyCreator的一个内部类继承了BeanFactoryAdvisorRetrievalHelper
    //BeanFactoryAdvisorRetrievalHelperAdapter重写了isEligibleBean方法
   this.advisorRetrievalHelper = new BeanFactoryAdvisorRetrievalHelperAdapter(beanFactory);
}

可以看到这个辅助类的创建是在回调setBeanFactory方法的时候执行的

org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans

public List<Advisor> findAdvisorBeans() {
   // Determine list of advisor bean names, if not cached already.
   //缓存的advisorName,避免每次都去从容器中找,消耗性能
   String[] advisorNames = this.cachedAdvisorBeanNames;
   //第一次进入肯定为null
   if (advisorNames == null) {
      // Do not initialize FactoryBeans here: We need to leave all regular beans
      // uninitialized to let the auto-proxy creator apply to them!
      //从容器中找到所有的advisor的名称
      advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
            this.beanFactory, Advisor.class, true, false);
      //把找到的advisor名称放到缓存中      
      this.cachedAdvisorBeanNames = advisorNames;
   }
   //如果容器中找不到,则直接放回空集合
   if (advisorNames.length == 0) {
      return new ArrayList<>();
   }

   List<Advisor> advisors = new ArrayList<>();
   for (String name : advisorNames) {
       //判断该advisor name是否是合格的
      if (isEligibleBean(name)) {
         if (this.beanFactory.isCurrentlyInCreation(name)) {
            if (logger.isTraceEnabled()) {
               logger.trace("Skipping currently created advisor '" + name + "'");
            }
         }
         else {
            try {
                //从容器中直接创建该advisor的实例
               advisors.add(this.beanFactory.getBean(name, Advisor.class));
            }
            catch (BeanCreationException ex) {
               Throwable rootCause = ex.getMostSpecificCause();
               if (rootCause instanceof BeanCurrentlyInCreationException) {
                  BeanCreationException bce = (BeanCreationException) rootCause;
                  String bceBeanName = bce.getBeanName();
                  if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
                     if (logger.isTraceEnabled()) {
                        logger.trace("Skipping advisor '" + name +
                              "' with dependency on currently created bean: " + ex.getMessage());
                     }
                     // Ignore: indicates a reference back to the bean we're trying to advise.
                     // We want to find advisors other than the currently created bean itself.
                     continue;
                  }
               }
               throw ex;
            }
         }
      }
   }
   //返回从容器中得到的所有advisor
   return advisors;
}

可以看到父类AbstractAdvisorAutoProxyCreator中的findCandidateAdvisors方法得到advisor的途径就是从容器中去寻找,接下来我们看第二种寻找advisor的途径,还是回到findCandidateAdvisors这个方法

protected List<Advisor> findCandidateAdvisors() {
   // Add all the Spring advisors found according to superclass rules.
   List<Advisor> advisors = super.findCandidateAdvisors();
   // Build Advisors for all AspectJ aspects in the bean factory.
   if (this.aspectJAdvisorsBuilder != null) {
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   }
   return advisors;
}

这里第二种途径寻找advisor主要是调用了一个aspectJAdvisorsBuilder去实现的,那么这个aspectJAdvisorsBuilder又是哪里来的?

@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {
   super.initBeanFactory(beanFactory);
   if (this.aspectJAdvisorFactory == null) {
      this.aspectJAdvisorFactory = new ReflectiveAspectJAdvisorFactory(beanFactory);
   }
   this.aspectJAdvisorsBuilder =
         new BeanFactoryAspectJAdvisorsBuilderAdapter(beanFactory, this.aspectJAdvisorFactory);
}

同样的它是在回调setBeanFactory方法的时候被创建的,具体的实现类是BeanFactoryAspectJAdvisorsBuilderAdapter,它是AnnotationAwareAspectJAutoProxyCreator的内部类并且继承了BeanFactoryAspectJAdvisorsBuilder。下面就主要来看下这个类是通过什么途径去寻找advisor的

org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors

public List<Advisor> buildAspectJAdvisors() {
   //缓存了aspect切面类的beanName,目的也是为了避免重复查找advisor,消耗性能
   List<String> aspectNames = this.aspectBeanNames;
   //第一次进来肯定为null
   if (aspectNames == null) {
      synchronized (this) {
         aspectNames = this.aspectBeanNames;
         if (aspectNames == null) {
            List<Advisor> advisors = new ArrayList<>();
            aspectNames = new ArrayList<>();
            //从容器中找出所有的bean的名称
            String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                  this.beanFactory, Object.class, true, false);
            //遍历容器中所有的bean      
            for (String beanName : beanNames) {
                //如果不是可用的就跳过
               if (!isEligibleBean(beanName)) {
                  continue;
               }
               // We must be careful not to instantiate beans eagerly as in this case they
               // would be cached by the Spring container but would not have been weaved.
               //获取该bean对应的class
               Class<?> beanType = this.beanFactory.getType(beanName);
               if (beanType == null) {
                  continue;
               }
               //判断这个bean是否是一个aspect切面类
               //这个advisorFactory前面的文章有说过这个api,具体的作用就是解析aspect切面类
               //进而得到asepct切面类中的advisor
               if (this.advisorFactory.isAspect(beanType)) {
                  aspectNames.add(beanName);
                  //AspectMetadata也在前面的AspectJProxyFactroy中有说到,作用是保存aspect切面类的元信息
                  AspectMetadata amd = new AspectMetadata(beanType, beanName);
                  if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                     //aspect实例化工厂,和之前说的实现不一样,这里的实现是BeanFactoryAspectInstanceFactory
                     //也就是说aspect这个切面类一定要从容器中拿到,所以我们在使用@Aspect注解的时候都要加上@Component注解
                     MetadataAwareAspectInstanceFactory factory =
                           new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                     //解析aspect切面类,把里面带有AspectJ注解的(除了@Pointcut)方法都封装成advisor并返回
                     List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
                     //判断这个aspect切面类是否是单例的
                     if (this.beanFactory.isSingleton(beanName)) {
                         //如果是单例的话就把解析出来的advisor放到缓存中,之后直接根据beanName就能拿到
                        this.advisorsCache.put(beanName, classAdvisors);
                     }
                     else {
                        否则如果是多例的,就把aspectFactory缓存起来,之后要拿advisor就得每次都要重新解析aspect切面类 
                        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;
         }
      }
   }
    //如果最终从容器中都找不到一个aspect切面类(也就解析不出advisor),那么就直接返回空集合
   if (aspectNames.isEmpty()) {
      return Collections.emptyList();
   }
   //第一次之后进来都会走这里,单例aspect切面类直接从缓存中取对应的advisor,多例就需要重新解析aspect切面类
   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;
}

整个buildAspectJAdvisors方法都比较重要,我们也可以知道第二种途径就是去寻找aspect切面类然后解析这个切面类得到里面的advisor

小总结:上面说了这么多都是在SpringIOC的bean实例化之前回调方法postProcessBeforeInstantiation中执行的,也就是说对于创建代理对象来说的一个前置工作,在这个方法中spring会去提前标记好哪些bean是不需要被代理的,在标记的过程中会去寻找所谓的advisor,而在寻找的过程中又会分为两个途径去寻找,第一种途径就是在父类AbstractAutoProxyCreator中实现从容器中去寻找所有的advisor,第二种途径是在AnnotationAwareAspectJAutoProxyCreator中实现寻找aspect切面类进而去解析该切面类得到里面所有的advisor,这两种寻找的途径都会使用一些缓存策略去进行减少性能的损耗,使得下次其他bean又被BeanPostProcessor拦截的时候能够直接从缓存中获取

创建代理对象

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization

根据SpringIOC的调用过程,bean执行到它的初始化完之后的阶段就会被来到此方法

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      //和循坏依赖有关,这里先忽略
      if (!this.earlyProxyReferences.contains(cacheKey)) {
         //wrapIfNecessary方法就是创建代理对象的核心方法 
         return wrapIfNecessary(bean, beanName, cacheKey);
      }
   }
   return bean;
}

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
      return bean;
   }
   //这里就是根据前面的创建代理的前置工作postProcessBeforeInstantiation去判断该对象是否需要创建代理
   if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
      return bean;
   }
   if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
      this.advisedBeans.put(cacheKey, Boolean.FALSE);
      return bean;
   }

   // Create proxy if we have advice.
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   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;
}

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean

protected Object[] getAdvicesAndAdvisorsForBean(
      Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
   //找到对于这个bean来说可用的advisor
   List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
   if (advisors.isEmpty()) {
      return DO_NOT_PROXY;
   }
   return advisors.toArray();
}

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
   //找到所有的candidate advisor,包括容器中的和解析aspect切面类得到的 
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   //在这些候选的advisor中寻找适合该bean使用的advisor
   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
   extendAdvisors(eligibleAdvisors);
   if (!eligibleAdvisors.isEmpty()) {
       //排序
      eligibleAdvisors = sortAdvisors(eligibleAdvisors);
   }
   return eligibleAdvisors;
}

关于findCandidateAdvisors方法前面已经说过了,就是通过父类AbstractAutoProxy去从容器中找到所有的advisor和子类AnnotationAwareAspectJAutoProxyCreator去从容器中找到aspect切面类从而解析这个切面类得到里面的advisor这两个途径去得到最终的advisor集合

org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findAdvisorsThatCanApply

protected List<Advisor> findAdvisorsThatCanApply(
      List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

   ProxyCreationContext.setCurrentProxiedBeanName(beanName);
   try {
      return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
   }
   finally {
      ProxyCreationContext.setCurrentProxiedBeanName(null);
   }
}

org.springframework.aop.support.AopUtils#findAdvisorsThatCanApply

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;
      }
      if (canApply(candidate, clazz, hasIntroductions)) {
         eligibleAdvisors.add(candidate);
      }
   }
   return eligibleAdvisors;
}

findAdvisorsThatCanApply这个方法在之前讲解AspectJProxyFactory的时候已经有说过了,主要做的就是去判断这些候选的candidate中哪些candidate是能够适用这个class的,其里面的判断是否适用的逻辑主要就是去遍历该class(包括其所有的父接口)的所有方法,每一个方法都使用advisor中的pointcut去进行判断过滤(利用了原生AspectJ的expression表达式过滤功能),只要其中有一个方法能够匹配这个advisor那么就把这个advisor放到可用的advisor集合中,表示该advisor适用于该class

回到org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary方法中

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
   if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
      return bean;
   }
   if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
      return bean;
   }
   if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
      this.advisedBeans.put(cacheKey, Boolean.FALSE);
      return bean;
   }

   // Create proxy if we have advice.
   //根据上面的分析可以知道该方法就是返回适用于该bean的所有advisor
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   //如果存在适用于该bean的advisor
   if (specificInterceptors != DO_NOT_PROXY) {
      //把该bean标记为已处理并且需要被代理 
      this.advisedBeans.put(cacheKey, Boolean.TRUE);
      //创建代理对象
      Object proxy = createProxy(
            bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
      this.proxyTypes.put(cacheKey, proxy.getClass());
      return proxy;
   }
   //如果不存在适用于该bean的advisor,那么就把该bean标记为已处理并且不需要被代理
   this.advisedBeans.put(cacheKey, Boolean.FALSE);
   return bean;
}

org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#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,因为AbstractAutoProxy也继承了ProxyConfig
  //所以AbstractAutoProxy也保存了关于aop代理配置的信息 
   proxyFactory.copyFrom(this);

   if (!proxyFactory.isProxyTargetClass()) {
      if (shouldProxyTargetClass(beanClass, beanName)) {
         proxyFactory.setProxyTargetClass(true);
      }
      else {
         evaluateProxyInterfaces(beanClass, proxyFactory);
      }
   }

   Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
   //添加筛选出来的advisor
   proxyFactory.addAdvisors(advisors);
   //添加目标源对象
   proxyFactory.setTargetSource(targetSource);
   customizeProxyFactory(proxyFactory);

   proxyFactory.setFrozen(this.freezeProxy);
   if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
   }
   //调用getProxy创建代理对象
   return proxyFactory.getProxy(getProxyClassLoader());
}

该方法就是主要负责创建代理对象的了,可以看到里面主要是使用了ProxyFactory这个底层API去实现的,主要就是调用ProxyFactory的添加advisor的API以及添加目标源的API,最后是调用getProxy这个API创建代理对象,至此,SpringAOP结合IOC容器创建代理对象已经完成了

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值