spring中aop的源码解析(三)

spring中aop的源码解析(三)

我们继续查看AbstractAspectJAutoProxyCreator中的wrapIfNecessary方法

Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);

这里是获取通知

protected Object[] getAdvicesAndAdvisorsForBean(
      Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
  //获取可用的Advisor列表
   List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
   if (advisors.isEmpty()) {
      return DO_NOT_PROXY;
   }
   return advisors.toArray();
}

上面方法很简单讲任务委派到findEligibleAdvisors方法上面去。

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
   //获取所有候选Advisor列表
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
  //从候选Advisor列表中找出那些能够适用于该类
   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
   extendAdvisors(eligibleAdvisors);
   if (!eligibleAdvisors.isEmpty()) {
     //对Advisor进行排序这里排序设计到Order
      eligibleAdvisors = sortAdvisors(eligibleAdvisors);
   }
   return eligibleAdvisors;
}

下面我们先从获取所有候选Advisor

protected List<Advisor> findCandidateAdvisors() {
   //网上说这里是从xml配置文件中获取候选的advisor列表
   List<Advisor> advisors = super.findCandidateAdvisors();
   //这里是从所有扫描加载进来的类中获取候选advisor列表
   if (this.aspectJAdvisorsBuilder != null) {
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
   }
   return advisors;
}

由于现在项目基本不用xml了加载bean我们就不进入分析直接看下面

BeanFactoryAspectJAdvisorsBuilder下面方法

public List<Advisor> buildAspectJAdvisors() {
   List<String> aspectNames = this.aspectBeanNames;

   if (aspectNames == null) {
      synchronized (this) {
         aspectNames = this.aspectBeanNames;
         if (aspectNames == null) {
            List<Advisor> advisors = new LinkedList<>();
            aspectNames = new LinkedList<>();
            //这里获取所有加载到spring容器中的对象名称
            String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
                  this.beanFactory, Object.class, true, false);
            for (String beanName : beanNames) {
               //判断是否为有效的bean
               if (!isEligibleBean(beanName)) {
                  continue;
               }
               //根据名称获取类对象
               Class<?> beanType = this.beanFactory.getType(beanName);
               if (beanType == null) {
                  continue;
               }
               //如果类对象上面存在@Aspect注解
               if (this.advisorFactory.isAspect(beanType)) {
                  aspectNames.add(beanName);
                  //创建Aspect元数据
                  AspectMetadata amd = new AspectMetadata(beanType, beanName);
                  //如果类时单例
                  if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                    //创建元数据aop实例化工厂
                     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 LinkedList<>();
   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;
}

 

我们重点分析ReflectiveAspectJAdvisorFactory 上面的getAdvisors

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
  //获取工厂上面保存的aop类对象
   Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
   //获取工厂类上面保存aop类的名称
   String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
   validate(aspectClass);

   MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
         new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

   List<Advisor> advisors = new LinkedList<>();
   //这里是整个方法的核心 获取aop类上面所有的方法一次遍历获取上面的通知
   for (Method method : getAdvisorMethods(aspectClass)) {
      Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
      if (advisor != null) {
         advisors.add(advisor);
      }
   }

   // If it's a per target aspect, emit the dummy instantiating aspect.
   if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
      Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
      advisors.add(0, instantiationAdvisor);
   }

   // Find introduction fields.
   for (Field field : aspectClass.getDeclaredFields()) {
      Advisor advisor = getDeclareParentsAdvisor(field);
      if (advisor != null) {
         advisors.add(advisor);
      }
   }

   return advisors;
}

我们看下获取aop类型上面所有的方法的函数

private List<Method> getAdvisorMethods(Class<?> aspectClass) {
   final List<Method> methods = new LinkedList<>();
   ReflectionUtils.doWithMethods(aspectClass, method -> {
      //这里就是获取被@Aspect注解修饰类上面的所有方法去掉Pointcut注解修饰的方法
      if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
         methods.add(method);
      }
   });
   methods.sort(METHOD_COMPARATOR);
   return methods;
}

下面我们看下根据类对象和方法对象获取通知的方法

public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
      int declarationOrderInAspect, String aspectName) {

   validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
   //这里更加类对象和方法获取上面注解封装为AspectJExpressionPointcut对象
   AspectJExpressionPointcut expressionPointcut = getPointcut(
         candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
   if (expressionPointcut == null) {
      return null;
   }
   //封装成InstantionModelAwarePointcutAdvisorImpl
   return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
         this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

下面我们进一步进入到封装成AspectJExpressionPointcut方法里面去

private AspectJExpressionPointcut getPointcut(Method candidateAdviceMethod, Class<?> candidateAspectClass) {
  //从候选方法上面获取AspectAnnotation注解
   AspectJAnnotation<?> aspectJAnnotation =
         AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
   if (aspectJAnnotation == null) {
      return null;
   }
 //封装为AspectJExpressionPointcut对象
   AspectJExpressionPointcut ajexp =
         new AspectJExpressionPointcut(candidateAspectClass, new String[0], new Class<?>[0]);
  //设置pointcut字符串表达式
   ajexp.setExpression(aspectJAnnotation.getPointcutExpression());
   if (this.beanFactory != null) {
      ajexp.setBeanFactory(this.beanFactory);
   }
   return ajexp;
}

 

我们再进入到findAspectJAnnotationOnMethod方法里面去

protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
   Class<?>[] classesToLookFor = new Class<?>[] {
         Before.class, Around.class, After.class, AfterReturning.class, AfterThrowing.class, Pointcut.class};
   for (Class<?> c : classesToLookFor) {
      AspectJAnnotation<?> foundAnnotation = findAnnotation(method, (Class<Annotation>) c);
      if (foundAnnotation != null) {
         return foundAnnotation;
      }
   }
   return null;
}

上面就是在获取方法上面含有Before,Aroud,After,AfterReturning,AfterThrowing,Pointcut方法

    原文作者:Spring Cloud
    原文地址: https://blog.csdn.net/yinbucheng/article/details/81080810
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞