Spring之深入解析AOP

概念

  • 切面Aspect
  • 连接点Joint point
  • 切入点Pointcut
  • 通知Advice
  • 目标对象Target
  • 织入Weave:指将切面应用到目标对象,并导致代理对象创建的过程

在【目标对象】中定位【切入点】,【织入】对应的【通知】,就变成了【代理对象】

类型

  • 前置通知:在方法执行前通知
  • 后置通知:在方法正常执行完成进行通知,可以访问到方法的返回值
  • 环绕通知:可以将要执行的方法(point.proceed())进行包裹执行,可以在前后添加需要执行的操作
  • 异常通知:在方法出现异常时进行通知,可以访问到异常对象,且可以指定在出现特定异常时在执行通知
  • 方法执行后通知: 在目标方法执行后无论是否发生异常,执行通知,不能访问目标方法的返回值

源码

解析XML

以XML配置为例:

<aop:config>
    <aop:aspect ref="myAdvice">
        <-- method : 指定通知类中的增强功能方法 -->
        <-- pointcut : 指定切入点,需要通过表达式来指定 -->
        <aop:before method="log" pointcut="execution(void demo.services.impl.DemoServiceImpl.hello(*))"/>
    </aop:aspect>
</aop:config>

根据 Namespace 在 spring.handler 找到对应标签的 NamespaceHandler,调用init()方法

<aop:config>标签找到对应的AopNamespaceHandlerinit()方法注册了多个解析器

<aop:config>标签对应的解析器就是ConfigBeanDefinitionParser,执行parse方法解析

public BeanDefinition parse(Element element, ParserContext parserContext) {
  CompositeComponentDefinition compositeDef =
    new CompositeComponentDefinition(element.getTagName(), parserContext.extractSource(element));
  parserContext.pushContainingComponent(compositeDef);

  // 向IoC容器中注册 AspectJAwareAdvisorAutoProxyCreator 类对应的 BeanDefinition:(用于创建AOP代理对象的)
  configureAutoProxyCreator(parserContext, element);

  // 获取<aop:config>标签的子标签<aop:aspect>、<aop:advisor> 、<aop:pointcut>
  List<Element> childElts = DomUtils.getChildElements(element);
  for (Element elt: childElts) {
    // 获取子标签的节点名称或者叫元素名称
    String localName = parserContext.getDelegate().getLocalName(elt);
    switch (localName) {
      case POINTCUT -> parsePointcut(elt, parserContext);
      case ADVISOR -> parseAdvisor(elt, parserContext);
      case ASPECT -> parseAspect(elt, parserContext);
    }
  }

  parserContext.popAndRegisterContainingComponent();
  return null;
}
  • <aop:point>标签,parsePointcut方法注册一个 AspectJExpressionPointcut 类对应的BeanDefinition对象,处理 pointcut
  • <aop:advisor>标签,parseAdvisor方法注册一个 DefaultBeanFactoryPointcutAdvisor 类对应的BeanDefinition对象,处理 advisor
  • <aop:aspect>标签,parseAspect创建多个BeanBeanDefinition
    • 创建MethodLocatingFactoryBean的BeanDefinition对象:用于获取Advice增强类的Method对象
    • 创建SimpleBeanFactoryAwareAspectInstanceFactory的BeanDefinition:用于创建增强类的实例
    • 以上的两个BeanDefinition的作用主要是通过反射调用Advice对象的指定方法method.invoke(obj,args)
    • 创建通知增强类的BeanDefinition对象,根据通知类型不同,分别创建对应的BeanDefinition
      • 前置通知:AspectJMethodBeforeAdvice
      • 后置通知:AspectJAfterAdvice
      • 方法执行后通知:AspectJAfterReturningAdvice
      • 异常通知:AspectJAfterThrowingAdvice
      • 环绕通知:AspectJAroundAdvice
    • 创建AspectJPointcutAdvisor类的BeanDefinition对象,AspectJPointcutAdvisor的构造函数的参数就是配置的通知增强类(前置通知、后置通知、方法执行后通知、异常通知、环绕通知)

一个<aop:aspect>对应一个切面,这里配置了<aop:aspect>,所以执行parseAspect方法

创建代理对象

AspectJAwareAdvisorAutoProxyCreator的父类AbstractAutoProxyCreator实现了BeanPostProcessor接口,会在实例init初始化方法执行完后调用postProcessAfterInitialization

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
  if (bean != null) {
    Object cacheKey = getCacheKey(bean.getClass(), beanName);
    if (this.earlyBeanReferences.remove(cacheKey) != bean) {
      // 如果有必要就产生代理对象
      return wrapIfNecessary(bean, beanName, cacheKey);
    }
  }
  return bean;
}
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.
  // 找到符合条件的拦截器
  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;
}

getAdvicesAndAdvisorsForBean找到符合Bean的拦截器,

protected Object[] getAdvicesAndAdvisorsForBean(
  Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {

  // 找到符合条件的Advisor
  List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);
  // 如果没有找到,返回空数组
  if (advisors.isEmpty()) {
    return DO_NOT_PROXY;
  }
  // 返回Advisor
  return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
  // 找到候选的Advisor(Advisor的实现类)
  List<Advisor> candidateAdvisors = findCandidateAdvisors();
  // 筛选符合条件的Advisor
  List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
  extendAdvisors(eligibleAdvisors);
  if (!eligibleAdvisors.isEmpty()) {
    eligibleAdvisors = sortAdvisors(eligibleAdvisors);
  }
  return eligibleAdvisors;
}

findAdvisorsThatCanApply调用AopUtil#findAdvisorsThatCanApply筛选符合条件的Advisor。

AopUtil#findAdvisorsThatCanApply调用canApply方法判断是否适用当前类。canApply方法有多个重载方法,最终调用以下的canApply方法

public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
  if (advisor instanceof IntroductionAdvisor ia) {
    return ia.getClassFilter().matches(targetClass);
  }
  // 如果Advisor是PointcutAdvisor
	// AspectJPointcutAdvisor 实现了 PointcutAdvisor 接口
  else if (advisor instanceof PointcutAdvisor pca) {
    // AspectJPointcutAdvisor#getPointcut获取到到是ComposablePointcut
    return canApply(pca.getPointcut(), targetClass, hasIntroductions);
  }
  else {
    // It doesn't have a pointcut so we assume it applies.
    return true;
  }
}

在XML解析时,会注册AspectJPointcutAdvisor类的BeanDefinition,内部的pointcut是一个ComposablePointcut(组合PointCut),其ClassFilterMethodMatcher其实是AspectJExpressionPointcutClassFilterMethodMatcherAspectJExpressionPointcut是在解析XML时注册的,解析切入点表达式。

public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
  Assert.notNull(pc, "Pointcut must not be null");
  // pointcut的类过滤器判断目标类是否符合
  if (!pc.getClassFilter().matches(targetClass)) {
    return false;
  }

  // pointcut的方法匹配器
  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 iamm) {
    introductionAwareMethodMatcher = iamm;
  }

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

AopUtil#canApply方法中,通过ClassFilterMethodMatcher方法的匹配来判断是否适用

createProxy方法调用了buildProxy,这个方法里通过代理工厂来创建代理对象

private Object buildProxy(Class<?> beanClass, @Nullable String beanName,
                          @Nullable Object[] specificInterceptors, TargetSource targetSource, boolean classOnly) {

  if (this.beanFactory instanceof ConfigurableListableBeanFactory clbf) {
    AutoProxyUtils.exposeTargetClass(clbf, beanName, beanClass);
  }

  // 创建代理工厂
  ProxyFactory proxyFactory = new ProxyFactory();
  proxyFactory.copyFrom(this);

  if (proxyFactory.isProxyTargetClass()) {
    // Explicit handling of JDK proxy targets and lambdas (for introduction advice scenarios)
    if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) {
      // Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
      for (Class<?> ifc : beanClass.getInterfaces()) {
        proxyFactory.addInterface(ifc);
      }
    }
  }
  else {
    // No proxyTargetClass flag enforced, let's apply our default checks...
    if (shouldProxyTargetClass(beanClass, beanName)) {
      proxyFactory.setProxyTargetClass(true);
    }
    else {
      evaluateProxyInterfaces(beanClass, proxyFactory);
    }
  }

  // 构建Advisor
  Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
  proxyFactory.addAdvisors(advisors);
  proxyFactory.setTargetSource(targetSource);
  customizeProxyFactory(proxyFactory);

  proxyFactory.setFrozen(this.freezeProxy);
  if (advisorsPreFiltered()) {
    proxyFactory.setPreFiltered(true);
  }

  // Use original ClassLoader if bean class not locally loaded in overriding class loader
  ClassLoader classLoader = getProxyClassLoader();
  if (classLoader instanceof SmartClassLoader smartClassLoader && classLoader != beanClass.getClassLoader()) {
    classLoader = smartClassLoader.getOriginalClassLoader();
  }
  return (classOnly ? proxyFactory.getProxyClass(classLoader) : proxyFactory.getProxy(classLoader));
}

调用了ProxyFactory#getProxy()方法

public Object getProxy(@Nullable ClassLoader classLoader) {
  return createAopProxy().getProxy(classLoader);
}

动态代理有Cglib和JDK两种,所以createAopProxy()会判断创建ObjenesisCglibAopProxy还是JdkDynamicAopProxy对象

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
  // 是否优化(强制使用cglib),默认false
  // 是否直接代理目标类,默认false
	// 没有实现接口,或者只实现了SpringProxy接口
  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) || ClassUtils.isLambdaClass(targetClass)) {
      return new JdkDynamicAopProxy(config);
    }
    // cglib动态代理
    return new ObjenesisCglibAopProxy(config);
  }
  else {
    // jdk动态代理
    return new JdkDynamicAopProxy(config);
  }
}

如果目标类实现了接口(除SpringProxy外),在默认情况下会采用JDK动态代理实现AOP,然后调用getProxy方法

public Object getProxy(@Nullable ClassLoader classLoader) {
  if (logger.isTraceEnabled()) {
    logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
  }
  return Proxy.newProxyInstance(determineClassLoader(classLoader), this.cache.proxiedInterfaces, this);
}

执行代理对象

而JdkDynamicAopProxy本身也是InvocationHandler,创建代理对象时把自己当作InvocationHandler参数传进去,所以在调用方法时,会执行JdkDynamicAopProxy#invoke()方法

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

  TargetSource targetSource = this.advised.targetSource;
  Object target = null;

  try {
    // equals方法
    if (!this.cache.equalsDefined && AopUtils.isEqualsMethod(method)) {
      // The target does not implement the equals(Object) method itself.
      return equals(args[0]);
    }
    // hashCode方法
    else if (!this.cache.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
      // The target does not implement the hashCode() method itself.
      return hashCode();
    }
    else if (method.getDeclaringClass() == DecoratingProxy.class) {
      // There is only getDecoratedClass() declared -> dispatch to proxy config.
      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;

    // 如果配置 exposeProxy 为 true,则把当前代理对象放到线程ThreadLocal
    // 当想要自己调自己同时代理不失效,可以配为true
    if (this.advised.exposeProxy) {
      // Make invocation available if necessary.
      oldProxy = AopContext.setCurrentProxy(proxy);
      setProxyContext = true;
    }

    // Get as late as possible to minimize the time we "own" the target,
    // in case it comes from a pool.
    target = targetSource.getTarget();
    Class<?> targetClass = (target != null ? target.getClass() : null);

    // Get the interception chain for this method.
    // 获取当前方法的拦截器链
    List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

    // Check whether we have any advice. If we don't, we can fall back on direct
    // reflective invocation of the target, and avoid creating a MethodInvocation.
    // 如果拦截器链为空直接反射调用目标方法
    if (chain.isEmpty()) {
      // We can skip creating a MethodInvocation: just invoke the target directly
      // Note that the final invoker must be an InvokerInterceptor so we know it does
      // nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
      Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
      retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
    }
    else {
      // We need to create a method invocation...
      // 构建MethodInvocation
      MethodInvocation invocation =
        new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
      // Proceed to the joinpoint through the interceptor chain.
      // 通过拦截器链执行连接点
      retVal = invocation.proceed();
    }

    // Massage return value if necessary.
    Class<?> returnType = method.getReturnType();
    if (retVal != null && retVal == target &&
        returnType != Object.class && returnType.isInstance(proxy) &&
        !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
      // Special case: it returned "this" and the return type of the method
      // is type-compatible. Note that we can't help if the target sets
      // a reference to itself in another returned object.
      retVal = proxy;
    }
    else if (retVal == null && returnType != void.class && returnType.isPrimitive()) {
      throw new AopInvocationException(
        "Null return value from advice does not match primitive return type for: " + method);
    }
    if (KotlinDetector.isSuspendingFunction(method)) {
      return COROUTINES_FLOW_CLASS_NAME.equals(new MethodParameter(method, -1).getParameterType().getName()) ?
        CoroutinesUtils.asFlow(retVal) : CoroutinesUtils.awaitSingleOrNull(retVal, args[args.length - 1]);
    }
    return retVal;
  }
  finally {
    if (target != null && !targetSource.isStatic()) {
      // Must have come from TargetSource.
      targetSource.releaseTarget(target);
    }
    if (setProxyContext) {
      // Restore old proxy.
      AopContext.setCurrentProxy(oldProxy);
    }
  }
}

获取拦截器链,AdvisedSupport#getInterceptorsAndDynamicInterceptionAdvice方法内部调用了DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice方法

public List<Object> getInterceptorsAndDynamicInterceptionAdvice(
  Advised config, Method method, @Nullable Class<?> targetClass) {

  // This is somewhat tricky... We have to process introductions first,
  // but we need to preserve order in the ultimate list.
  // 这里是DefaultAdvisorAdapterRegistry对象
  // 注册了几个适配器:MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter
  // 适配器用于将通知增强类包装成拦截器,在执行代理对象时也是调用拦截器
  AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
  Advisor[] advisors = config.getAdvisors();
  List<Object> interceptorList = new ArrayList<>(advisors.length);
  Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
  Boolean hasIntroductions = null;

  for (Advisor advisor : advisors) {
    // 如果advisor是PointcutAdvisor
    // 解析时注册了AspectJPointcutAdvisor,所以AspectJPointcutAdvisor会走这个if分支
    if (advisor instanceof PointcutAdvisor pointcutAdvisor) {
      // Add it conditionally.
      // ClassFilter匹配目标类
      if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
        // MethodMatcher匹配目标方法
        MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
        boolean match;
        if (mm instanceof IntroductionAwareMethodMatcher iamm) {
          if (hasIntroductions == null) {
            hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
          }
          match = iamm.matches(method, actualClass, hasIntroductions);
        }
        else {
          match = mm.matches(method, actualClass);
        }
        // 如果匹配成功
        if (match) {
          // 调用DefaultAdvisorAdapterRegistry#getInterceptors获取拦截器
          // 这里将通知增强类包装成拦截器
          MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
          if (mm.isRuntime()) {
            // Creating a new object instance in the getInterceptors() method
            // isn't a problem as we normally cache created chains.
            for (MethodInterceptor interceptor : interceptors) {
              interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
            }
          }
          else {
            interceptorList.addAll(Arrays.asList(interceptors));
          }
        }
      }
    }
    else if (advisor instanceof IntroductionAdvisor ia) {
      if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
        Interceptor[] interceptors = registry.getInterceptors(advisor);
        interceptorList.addAll(Arrays.asList(interceptors));
      }
    }
    else {
      Interceptor[] interceptors = registry.getInterceptors(advisor);
      interceptorList.addAll(Arrays.asList(interceptors));
    }
  }

  return interceptorList;
}

DefaultAdvisorAdapterRegistry#getInterceptors方法,将通知增强类包装成了拦截器

public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
  List<MethodInterceptor> interceptors = new ArrayList<>(3);
  // 获取通知增强器对象
  Advice advice = advisor.getAdvice();
  // 如果通知增强器对象是MethodInterceptor(AspectJAroundAdvice、AspectJAfterAdvice、AspectJAfterThrowingAdvice),直接添加到集合
  if (advice instanceof MethodInterceptor methodInterceptor) {
    interceptors.add(methodInterceptor);
  }
  // 遍历适配器
  // 也就是注册的MethodBeforeAdviceAdapter、AfterReturningAdviceAdapter、ThrowsAdviceAdapter
  for (AdvisorAdapter adapter : this.adapters) {
    // 如果适配器支持这个通知增强器对象,也就是MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice
    if (adapter.supportsAdvice(advice)) {
      // 把通知增强器对象包装成拦截器对象,添加到集合
      interceptors.add(adapter.getInterceptor(advisor));
    }
  }
  if (interceptors.isEmpty()) {
    throw new UnknownAdviceTypeException(advisor.getAdvice());
  }
  // 返回拦截器数组
  return interceptors.toArray(new MethodInterceptor[0]);
}

在解析XML时,如果是环绕通知、后置通知、异常通知,注册的通知增强器对象,直接实现了MethodInterceptor接口

  • AspectJAroundAdvice
  • AspectJAfterAdvice
  • AspectJAfterThrowingAdvice

获取拦截器链,把通知增强器对象(MethodBeforeAdvice、AfterReturningAdvice、ThrowsAdvice)包装成了拦截器,其中

在执行代理对象时也是调用拦截器,有以下六种拦截器:

  • MethodBeforeAdviceInterceptor
  • AfterReturningAdviceInterceptor
  • ThrowsAdviceInterceptor

以上三个拦截器包装成动态拦截器InterceptorAndDynamicMethodMatcher返回

class InterceptorAndDynamicMethodMatcher {

  final MethodInterceptor interceptor;

  final MethodMatcher methodMatcher;

  public InterceptorAndDynamicMethodMatcher(MethodInterceptor interceptor, MethodMatcher methodMatcher) {
    this.interceptor = interceptor;
    this.methodMatcher = methodMatcher;
  }

}

构建ReflectiveMethodInvocation对象,执行proceed()方法

public Object proceed() throws Throwable {
  // We start with an index of -1 and increment early.
  // 如果拦截器已经执行完,执行连接点方法
  if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
    return invokeJoinpoint();
  }

  // 获取拦截器
  Object interceptorOrInterceptionAdvice =
    this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
  if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher dm) {
    // Evaluate dynamic method matcher here: static part will already have
    // been evaluated and found to match.
    Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
    // 动态判断拦截器是否匹配
    if (dm.matcher().matches(this.method, targetClass, this.arguments)) {
      // 匹配成功,执行拦截器
      // 在拦截器的invoke方法中,还会调用ReflectiveMethodInvocation的proceed方法,也就是当前proceed方法
      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);
  }
}

执行动态拦截器InterceptorAndDynamicMethodMatcher#matcher()得到MethodMatcher,因为目标类有多个方法,所以在执行方法时,判断当前执行的方法是否是切入点,如果是切入点,则执行拦截器的invoke方法

MethodBeforeAdviceInterceptor#invoke()为例子

public Object invoke(MethodInvocation mi) throws Throwable {
  // 在目标方法执行前调用AspectJMethodBeforeAdvice#before()方法
  this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
  // 调用ReflectiveMethodInvocation#proceed()方法,会继续执行拦截器链
  return mi.proceed();
}

但是AspectJAroundAdvice比较特殊

public Object invoke(MethodInvocation mi) throws Throwable {
  if (!(mi instanceof ProxyMethodInvocation pmi)) {
    throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi);
  }
  // 获取ProceedingJoinPoint对象
  ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi);
  // 获取JoinPointMatch对象,用于匹配切点
  JoinPointMatch jpm = getJoinPointMatch(pmi);
  // 执行环绕通知的逻辑
  // 把ProceedingJoinPoint以参数形式传入通知增强方法
  // 需要我们自己在通知增强方法调用ProceedingJoinPoint#proceed方法执行目标方法
  return invokeAdviceMethod(pjp, jpm, null, null);
}
  • 23
    点赞
  • 26
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值