spring源码---Aop:匹配Bean

一,AbstractAutoProxyCreator

1.BeanPostProcessor接口的两个方法

   before方法没有内容,而该类的PostProcessAfterInitialization()方法,进行了操作

public Object postProcessBeforeInitialization(Object bean, String beanName) {
   return bean;
}
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
   if (bean != null) {
      Object cacheKey = getCacheKey(bean.getClass(), beanName);
      if (this.earlyProxyReferences.remove(cacheKey) != bean) {
         return wrapIfNecessary(bean, beanName, cacheKey); //【入】
      }
   }
   return bean;
}

这个方法是一个入口,重点是在wrapIfNecessary()方法上面:

protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    ...
   //判断是否需要 代理这个Bean
   if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
      return bean;
   }
    //是否应该跳过,与实例化before()一样
   if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
      this.advisedBeans.put(cacheKey, Boolean.FALSE);
      return bean;
   }
   //1.获取匹配成功的Advisor
   Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
   if (specificInterceptors != DO_NOT_PROXY) {
      this.advisedBeans.put(cacheKey, Boolean.TRUE);
      //2.创建代理
      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;
}

二,获得匹配成功的Advisor类列表

判断是否需要代理: 位于子类AbstractAdvisorAutoProxyCreator类中

protected Object[] getAdvicesAndAdvisorsForBean(...) {
   List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
   if (advisors.isEmpty()) {
      return DO_NOT_PROXY;
   }
   return advisors.toArray();
}

获得advisor

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
   List<Advisor> candidateAdvisors = findCandidateAdvisors(); //从Helper中获取。直接获取全部advisor
   //筛选!【重点】
   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName); 
   extendAdvisors(eligibleAdvisors);
   if (!eligibleAdvisors.isEmpty()) {
      eligibleAdvisors = sortAdvisors(eligibleAdvisors);
   }
   return eligibleAdvisors;
}

在第一步中,获得全部advisor,也就是通知类中的方法,注意这个时候方法里面的 pointcut只有一个string值

第二步,开始匹配,findAdvisorsThatCanApply()

protected List<Advisor> findAdvisorsThatCanApply(
      List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
      return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass); //【入】
}
AopUtils类中:
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);
      }
   } //赛选 非该接口实现的advisor
   boolean hasIntroductions = !eligibleAdvisors.isEmpty(); //空的,则设置未false
   for (Advisor candidate : candidateAdvisors) {  //再来一遍筛选
      if (candidate instanceof IntroductionAdvisor) {
         // already processed
         continue;
      }//第三个不再是默认值,表示是否处理,如果已经有值,则为true
      if (canApply(candidate, clazz, hasIntroductions)) {
         eligibleAdvisors.add(candidate);
      }
   }
   return eligibleAdvisors;
}

这里主要是区分两个接口的实现,分别处理,下面看两个接口体系的不同“

IntroductionAdvisor接口体系:

 

pointcutAdvisor接口体系: 显然我们走该接口的if

核心方法在canApply()中,这里有一个小入口,和一个重载,用来区分是否已经处理过等等情况,最终都最走向

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
   if (advisor instanceof IntroductionAdvisor) {
      return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
   }
   else if (advisor instanceof PointcutAdvisor) {
      PointcutAdvisor pca = (PointcutAdvisor) advisor;
      return canApply(pca.getPointcut(), targetClass, hasIntroductions); //是否匹配切点表达式
   }
   else {
      return true;
   }
}

同样,我们走第二个if情况,再一次进行canApply()方法:

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
  //【重点】
   if (!pc.getClassFilter().matches(targetClass)) { //匹配
      return false;
   }

   MethodMatcher methodMatcher = pc.getMethodMatcher();
   if (methodMatcher == MethodMatcher.TRUE) {
      // No need to iterate the methods if we're matching any method anyway...
      return true;
   }

   IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
   if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
      introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
   }

   Set<Class<?>> classes = new LinkedHashSet<>();
   if (!Proxy.isProxyClass(targetClass)) {
      classes.add(ClassUtils.getUserClass(targetClass));
   }
   classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));

   for (Class<?> clazz : classes) {
      Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
      for (Method method : methods) {
         if (introductionAwareMethodMatcher != null ?
               introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
               methodMatcher.matches(method, targetClass)) {
            return true;
         }
      }
   }

   return false;
}

核心代码在第一行if中就已经体现了,两个方法,一个对具体的pointCut进行了实例化,第二个方法直接进行了匹配,提取告诉你,他们的具体实现都是交给了AspectJ包进行处理的!

  1. 处理pointCut

public ClassFilter getClassFilter() {
   obtainPointcutExpression();
   return this;
}
private PointcutExpression obtainPointcutExpression() {
   if (getExpression() == null) { //表达式不存在,直接抛出异常
      throw new IllegalStateException("Must set property 'expression' before attempting to match");
   }
   if (this.pointcutExpression == null) {
      this.pointcutClassLoader = determinePointcutClassLoader();
      this.pointcutExpression = buildPointcutExpression(this.pointcutClassLoader);
   }
   return this.pointcutExpression;
}

1.1.ClassLoader获取,类加载器,获取BeanFactory的类加载器。

private ClassLoader determinePointcutClassLoader() {
   if (this.beanFactory instanceof ConfigurableBeanFactory) { //走这里
      return ((ConfigurableBeanFactory) this.beanFactory).getBeanClassLoader();
   }
   if (this.pointcutDeclarationScope != null) {
      return this.pointcutDeclarationScope.getClassLoader();
   }
   return ClassUtils.getDefaultClassLoader();
}

1.2.Expression实例化:

private PointcutExpression buildPointcutExpression(@Nullable ClassLoader classLoader) {
   PointcutParser parser = initializePointcutParser(classLoader); //根据类加载器获得 解析器
   PointcutParameter[] pointcutParameters = new PointcutParameter[this.pointcutParameterNames.length];
   for (int i = 0; i < pointcutParameters.length; i++) {
      pointcutParameters[i] = parser.createPointcutParameter(
            this.pointcutParameterNames[i], this.pointcutParameterTypes[i]);
   }
    //解析,具体交给Aspect包
   return parser.parsePointcutExpression(replaceBooleanOperators(resolveExpression()),
         this.pointcutDeclarationScope, pointcutParameters);
}

2.匹配

public boolean matches(Class<?> targetClass) {
//获得切入点的详细信息
   PointcutExpression pointcutExpression = obtainPointcutExpression();
   try {
      try {  //交给Aspect 处理
         return pointcutExpression.couldMatchJoinPointsInType(targetClass);
      }
   return false;
}

到了此处,获得了匹配成功的Advisor类的时候,开始创建代理,请看下一节。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值