spring源碼解析-基于注解的SpringAOP源碼解析(二)

Spring源碼解析之基于注解的SpringAOP源碼解析(一)中济欢,我們搭建了SpringAOP源碼分析的環(huán)境凛膏,介紹了@EnableAspectJAutoProxy注解和postProcessBeforeInstantiation方法是如何加載所有增強的。本篇文章則將描述一下AOP中剩余的實現(xiàn)邏輯

postProcessAfterInitialization

這個方法是在bean實例化之后調(diào)用的,它是適用于所有需要被代理的類的

public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        if (!this.earlyProxyReferences.contains(cacheKey)) {
        //往下看
            return wrapIfNecessary(bean, beanName, cacheKey);
        }
    }
    return bean;
}
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
//如果已經(jīng)處理過
    if (beanName != null && this.targetSourcedBeans.contains(beanName)) {
        return bean;
    }
    //如果當(dāng)前類是增強類
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
        return bean;
    }
    //查看類是否是基礎(chǔ)設(shè)施類,或者是否被排除
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
        this.advisedBeans.put(cacheKey, Boolean.FALSE);
        return bean;
    }
//校驗此類是否應(yīng)該被代理,獲取這個類的增強
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
//如果獲取到了增強則需要針對增強創(chuàng)建代理
if (specificInterceptors != DO_NOT_PROXY) {
    this.advisedBeans.put(cacheKey, Boolean.TRUE);
    //創(chuàng)建代理
    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;

}
上方這段代理一共有兩個重點风题,getAdvicesAndAdvisorsForBean和createProxy這兩個方法

獲取增強

protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {
//往下看
    List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
    if (advisors.isEmpty()) {
        return DO_NOT_PROXY;
    }
    return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
    //獲取容器中的所有增強
    List<Advisor> candidateAdvisors = findCandidateAdvisors();
    //驗證beanClass是否該被代理,如果應(yīng)該嫉父,則返回適用于這個bean的增強
    List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
    extendAdvisors(eligibleAdvisors);
    if (!eligibleAdvisors.isEmpty()) {
        eligibleAdvisors = sortAdvisors(eligibleAdvisors);
    }
    return eligibleAdvisors;
}

上方這個獲取增強又分成了2部分沛硅,獲取全部和根據(jù)全部處理bean相關(guān)的

獲取全部增強

protected List<Advisor> findCandidateAdvisors() {
    // 調(diào)用父類的方法加載配置文件中的AOP聲明(注解與XML都存在的時候)
    List<Advisor> advisors = super.findCandidateAdvisors();
        //往下看
        if (this.aspectJAdvisorsBuilder != null) {
      advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
    }
    return advisors;
  }

下面的方法就是獲取所有的增強的代碼實現(xiàn)了,方法比較長绕辖,不過主要邏輯很少摇肌。
1.獲取所有beanName
2.找出所有標記Aspect注解的類
3.對標記Aspect的類提取增強器

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<>();
                    //獲取所有的bean
          String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
              this.beanFactory, Object.class, true, false);
          for (String beanName : beanNames) {
                      //校驗不合法的類,Spring的一個擴展點仪际,可以從子類中做排除切面的操作
            if (!isEligibleBean(beanName)) {
              continue;
            }
            //獲取bean的類型
            Class<?> beanType = this.beanFactory.getType(beanName);
            if (beanType == null) {
              continue;
            }
                        //是否帶有Aspect注解
            if (this.advisorFactory.isAspect(beanType)) {
              aspectNames.add(beanName);
              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 {
                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;

  }

接下來就是各個增強器的獲取方法的實現(xiàn)

接下來就是各個增強器的獲取方法的實現(xiàn)

public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
        //獲取所有Aspect類、類名稱树碱、并校驗
    Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
    validate(aspectClass);


    MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
        new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
    
    List<Advisor> advisors = new LinkedList<>();
        //取出類的所有方法
    for (Method method : getAdvisorMethods(aspectClass)) {
            //獲取增強方法肯适,往下看
      Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
      if (advisor != null) {
        advisors.add(advisor);
      }
    }
    
    // 如果需要增強且配置了延遲增強則在第一個位置添加同步實例化增強方法
    if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
      Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
      advisors.add(0, instantiationAdvisor);
    }
    
    // 獲取屬性中配置DeclareParents注解的增強
    for (Field field : aspectClass.getDeclaredFields()) {
      Advisor advisor = getDeclareParentsAdvisor(field);
      if (advisor != null) {
        advisors.add(advisor);
      }
    }
    
    return advisors;

  }

普通增強的獲取

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

    validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
        //獲取切點
    AspectJExpressionPointcut expressionPointcut = getPointcut(
        candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
    if (expressionPointcut == null) {
      return null;
    }
        //根據(jù)切點生成增強
    return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
        this, aspectInstanceFactory, declarationOrderInAspect, aspectName);

  }

上方代碼又分為了兩部分,先看一下切點信息的獲取

public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
    MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

  this.declaredPointcut = declaredPointcut;
  this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
  this.methodName = aspectJAdviceMethod.getName();
  this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
  this.aspectJAdviceMethod = aspectJAdviceMethod;
  this.aspectJAdvisorFactory = aspectJAdvisorFactory;
  this.aspectInstanceFactory = aspectInstanceFactory;
  this.declarationOrder = declarationOrder;
  this.aspectName = aspectName;

  if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
    Pointcut preInstantiationPointcut = Pointcuts.union(
        aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
    this.pointcut = new PerTargetInstantiationModelPointcut(
        this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
    this.lazy = true;
  }
  else {
    this.pointcut = this.declaredPointcut;
    this.lazy = false;
           //初始化對應(yīng)的增強器成榜,重點
    this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);
  }
}

到這里之后獲取所有的增強這個流程就快要完畢了

private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
        //往下看
    Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
        this.aspectInstanceFactory, this.declarationOrder, this.aspectName);
    return (advice != null ? advice : EMPTY_ADVICE);
  }
    
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {

    Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
    validate(candidateAspectClass);
    
    AspectJAnnotation<?> aspectJAnnotation =
        AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);
    if (aspectJAnnotation == null) {
      return null;
    }
    
    if (!isAspect(candidateAspectClass)) {
      throw new AopConfigException("Advice must be declared inside an aspect type: " +
          "Offending method '" + candidateAdviceMethod + "' in class [" +
          candidateAspectClass.getName() + "]");
    }
    
    if (logger.isDebugEnabled()) {
      logger.debug("Found AspectJ method: " + candidateAdviceMethod);
    }
    
    AbstractAspectJAdvice springAdvice;
        //根據(jù)不同的注解類型封裝不同的增強器
    switch (aspectJAnnotation.getAnnotationType()) {
      case AtBefore:
        springAdvice = new AspectJMethodBeforeAdvice(
            candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
        break;
      case AtAfter:
        springAdvice = new AspectJAfterAdvice(
            candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
        break;
      case AtAfterReturning:
        springAdvice = new AspectJAfterReturningAdvice(
            candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
        AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
        if (StringUtils.hasText(afterReturningAnnotation.returning())) {
          springAdvice.setReturningName(afterReturningAnnotation.returning());
        }
        break;
      case AtAfterThrowing:
        springAdvice = new AspectJAfterThrowingAdvice(
            candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
        AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
        if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
          springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
        }
        break;
      case AtAround:
        springAdvice = new AspectJAroundAdvice(
            candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
        break;
      case AtPointcut:
        if (logger.isDebugEnabled()) {
          logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
        }
        return null;
      default:
        throw new UnsupportedOperationException(
            "Unsupported advice type on method: " + candidateAdviceMethod);
    }
    
    springAdvice.setAspectName(aspectName);
    springAdvice.setDeclarationOrder(declarationOrder);
    String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
    if (argNames != null) {
      springAdvice.setArgumentNamesFromStringArray(argNames);
    }
    springAdvice.calculateArgumentBindings();
    return springAdvice;

  }

獲取匹配增強

經(jīng)過上方的長篇大論框舔,我們終于完成了所有的增強器的解析,還記得剛才的方法走到哪了么

protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
   //獲取全部增強
  List<Advisor> candidateAdvisors = findCandidateAdvisors();
  List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
  extendAdvisors(eligibleAdvisors);
  if (!eligibleAdvisors.isEmpty()) {
    eligibleAdvisors = sortAdvisors(eligibleAdvisors);
  }
  return eligibleAdvisors;
}

接下來看看怎么為當(dāng)前的Bean匹配自己的增強吧

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

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

  }
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
    if (candidateAdvisors.isEmpty()) {
        return candidateAdvisors;
    }
    List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();
    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) {
            continue;
        }
        //對普通bean的處理
        if (canApply(candidate, clazz, hasIntroductions)) {
            eligibleAdvisors.add(candidate);
        }
    }
    return eligibleAdvisors;
}

引介增強與普通bean的處理最后都是進的同一個方法,只不過是引介增強的第三個參數(shù)默認使用的false

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;
    }
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
    Assert.notNull(pc, "Pointcut must not be null");
    //切點上是否存在排除類的配置
    if (!pc.getClassFilter().matches(targetClass)) {
        return false;
    }
    //驗證注解的作用域是否可以作用于方法上
    MethodMatcher methodMatcher = pc.getMethodMatcher();
    if (methodMatcher == MethodMatcher.TRUE) {  
        return true;
    }

    IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
    if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
        introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
    }
    
    Set<Class<?>> classes = new LinkedHashSet<Class<?>>(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
    classes.add(targetClass);
    for (Class<?> clazz : classes) {
        Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);
        for (Method method : methods) {
            //獲取類所實現(xiàn)的所有接口和所有類層級的方法挣输,循環(huán)驗證
            if ((introductionAwareMethodMatcher != null &&
                    introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions)) ||
                    methodMatcher.matches(method, targetClass)) {
                return true;
            }
        }
    }
    
    return false;

}

現(xiàn)在所有的bean對應(yīng)的增強都已經(jīng)獲取到了纬凤,那么就可以根據(jù)類的所有增強數(shù)組創(chuàng)建代理

創(chuàng)建代理

回到最上方開始獲取增強的地方,當(dāng)增強獲取到之后就可以執(zhí)行下面這個操作了

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對象copy當(dāng)前類中的相關(guān)屬性
    proxyFactory.copyFrom(this);
        //判斷是否使用Cglib動態(tài)代理
    if (!proxyFactory.isProxyTargetClass()) {
          //如果配置開啟使用則直接設(shè)置開啟
      if (shouldProxyTargetClass(beanClass, beanName)) {
        proxyFactory.setProxyTargetClass(true);
      }
      else {
            //如果沒有配置開啟則判斷bean是否有合適的接口使用JDK的動態(tài)代理(JDK動態(tài)代理必須是帶有接口的類歧焦,如果類沒有實現(xiàn)任何接口則只能使用Cglib動態(tài)代理)
            //關(guān)于代理的基礎(chǔ)知識可以參考我的另一篇文章:https://mp.weixin.qq.com/s/1DRmvuky5_NMRcH-toTLqQ
        evaluateProxyInterfaces(beanClass, proxyFactory);
      }
    }
        //添加所有增強
    Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
    proxyFactory.addAdvisors(advisors);
        //設(shè)置要代理的類
    proxyFactory.setTargetSource(targetSource);
        //Spring的一個擴展點移斩,默認實現(xiàn)為空肚医。留給我們在需要對代理進行特殊操作的時候?qū)崿F(xiàn)
    customizeProxyFactory(proxyFactory);
    proxyFactory.setFrozen(this.freezeProxy);
    if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
    }
        //使用代理工廠獲取代理對象
    return proxyFactory.getProxy(getProxyClassLoader());

  }

獲取代理對象

public Object getProxy(@Nullable ClassLoader classLoader) {
    return createAopProxy().getProxy(classLoader);
  }
protected final synchronized AopProxy createAopProxy() {
    if (!this.active) {
      activate();
    }
    return getAopProxyFactory().createAopProxy(this);
  }
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    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.");
      }
      if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
        return new JdkDynamicAopProxy(config);
      }
      return new ObjenesisCglibAopProxy(config);
    }
    else {
      return new JdkDynamicAopProxy(config);
    }
  }

增強何時調(diào)用绢馍?

代理創(chuàng)建出來了向瓷,那么我們的前置增強、后置增強舰涌、環(huán)繞增強等是如何在代理中體現(xiàn)的呢猖任,對代理模式還不熟悉的同學(xué)一定要先看一下這篇文章呦:https://mp.weixin.qq.com/s/1DRmvuky5_NMRcH-toTLqQ
這里就簡單看一下JDK動態(tài)代理的實現(xiàn)吧

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    MethodInvocation invocation;
    Object oldProxy = null;
    boolean setProxyContext = false;

    TargetSource targetSource = this.advised.targetSource;
    Object target = null;
    
    try {
            //equals方法處理
      if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
        return equals(args[0]);
      }
            //hash代碼處理
      else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
        return hashCode();
      }
      else if (method.getDeclaringClass() == DecoratingProxy.class) {
        return AopProxyUtils.ultimateTargetClass(this.advised);
      }
      else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
          method.getDeclaringClass().isAssignableFrom(Advised.class)) {
        // Service invocations on ProxyConfig with the proxy config...
        return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
      }
    
      Object retVal;
            //如果配置內(nèi)部方法調(diào)用的增強
      if (this.advised.exposeProxy) {
        oldProxy = AopContext.setCurrentProxy(proxy);
        setProxyContext = true;
      }
    
      target = targetSource.getTarget();
      Class<?> targetClass = (target != null ? target.getClass() : null);
    
      // 獲取當(dāng)前方法的攔截器鏈
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
    
      if (chain.isEmpty()) {
                //如果沒有攔截器直接調(diào)用切點方法
        Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
        retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
      }
      else {
        invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                //執(zhí)行攔截器鏈,重點瓷耙,往下看
        retVal = invocation.proceed();
      }
    
      Class<?> returnType = method.getReturnType();
            //返回結(jié)果
      if (retVal != null && retVal == target &&
          returnType != Object.class && returnType.isInstance(proxy) &&
          !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
        retVal = proxy;
      }
      else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
        throw new AopInvocationException(
            "Null return value from advice does not match primitive return type for: " + method);
      }
      return retVal;
    }
    finally {
      if (target != null && !targetSource.isStatic()) {
        targetSource.releaseTarget(target);
      }
      if (setProxyContext) {
        AopContext.setCurrentProxy(oldProxy);
      }
    }

  }

看完上方的代碼朱躺,可以猜到,所有的增強都在這個攔截器里面了搁痛,那么這個攔截器又是如何實現(xiàn)的呢

public Object proceed() throws Throwable {
    //  執(zhí)行完所有的增強后執(zhí)行切點方法
    if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
      return invokeJoinpoint();
    }
        //獲取下一個要執(zhí)行的攔截器
    Object interceptorOrInterceptionAdvice =
        this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
    if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
      InterceptorAndDynamicMethodMatcher dm =
          (InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
      if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
        return dm.interceptor.invoke(this);
      }
      else {
        // Dynamic matching failed.
        // Skip this interceptor and invoke the next in the chain.
        return proceed();
      }
    }
    else {
      // It's an interceptor, so we just invoke it: The pointcut will have
      // been evaluated statically before this object was constructed.
      return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
    }
  }

至此SpringAOP的源碼解析已經(jīng)完成

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末长搀,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子鸡典,更是在濱河造成了極大的恐慌源请,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,602評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件彻况,死亡現(xiàn)場離奇詭異谁尸,居然都是意外死亡,警方通過查閱死者的電腦和手機纽甘,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,442評論 2 382
  • 文/潘曉璐 我一進店門良蛮,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人悍赢,你說我怎么就攤上這事决瞳。” “怎么了左权?”我有些...
    開封第一講書人閱讀 152,878評論 0 344
  • 文/不壞的土叔 我叫張陵瞒斩,是天一觀的道長。 經(jīng)常有香客問我涮总,道長胸囱,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,306評論 1 279
  • 正文 為了忘掉前任瀑梗,我火速辦了婚禮烹笔,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘抛丽。我一直安慰自己谤职,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 64,330評論 5 373
  • 文/花漫 我一把揭開白布亿鲜。 她就那樣靜靜地躺著允蜈,像睡著了一般冤吨。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上饶套,一...
    開封第一講書人閱讀 49,071評論 1 285
  • 那天漩蟆,我揣著相機與錄音,去河邊找鬼妓蛮。 笑死怠李,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的蛤克。 我是一名探鬼主播捺癞,決...
    沈念sama閱讀 38,382評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼构挤!你這毒婦竟也來了髓介?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,006評論 0 259
  • 序言:老撾萬榮一對情侶失蹤筋现,失蹤者是張志新(化名)和其女友劉穎唐础,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體夫否,經(jīng)...
    沈念sama閱讀 43,512評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡彻犁,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,965評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了凰慈。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片汞幢。...
    茶點故事閱讀 38,094評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖微谓,靈堂內(nèi)的尸體忽然破棺而出森篷,到底是詐尸還是另有隱情,我是刑警寧澤豺型,帶...
    沈念sama閱讀 33,732評論 4 323
  • 正文 年R本政府宣布仲智,位于F島的核電站,受9級特大地震影響姻氨,放射性物質(zhì)發(fā)生泄漏钓辆。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,283評論 3 307
  • 文/蒙蒙 一肴焊、第九天 我趴在偏房一處隱蔽的房頂上張望前联。 院中可真熱鬧,春花似錦娶眷、人聲如沸似嗤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,286評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽烁落。三九已至乘粒,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間伤塌,已是汗流浹背灯萍。 一陣腳步聲響...
    開封第一講書人閱讀 31,512評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留寸谜,地道東北人竟稳。 一個月前我還...
    沈念sama閱讀 45,536評論 2 354
  • 正文 我出身青樓属桦,卻偏偏與公主長得像熊痴,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子聂宾,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,828評論 2 345

推薦閱讀更多精彩內(nèi)容