SpringBoot之AOP

AOP(Aspect-Oriented Programming) 面向切面编程。Spring Aop 在 Spring框架中的地位举足轻重,主要用于实现事务、缓存、安全等功能。

AOP的实现本质就是动态代理,下面从源码角度来分析spring的AOP实现原理


AOP的使用

下面是AOP的注解实现,也是SpringBoot中实现AOP最常见的方式

@Aspect
public class AspectTest {

    @Pointcut("execution(public * com.miaosha.controller.*.*(..))")
    public void aspect(){}

    @Before("aspect()")
    public void before(){
        System.out.println("before aspect");
    }

    @After("aspect()")
    public void after(){
        System.out.println("after aspect");
    }

}

上面这段代码的功能是对com.miaosha.controller包下面的每个类的每一个方法进行增强,增强的内容就是每个方法最前面打印"before aspect",最后打印"after aspect"


AOP实现的大致流程主要分为三个步骤:

  1. 创建AnnotationAwareAspectJAutoProxyCreator对象
  2. 扫描容器中的切面,创建PointcutAdvisor对象
  3. 生成代理类

1、创建AnnotationAwareAspectJAutoProxyCreator对象

AnnotationAwareAspectJAutoProxyCreator类是spring实现AOP至关重要的类,它是在SpringBoot自动装配的时候被加载的,自动装配之前已经详细讲过,这里可以看到有一个AopAutoConfiguration

在这里插入图片描述

@Configuration
@ConditionalOnClass({ EnableAspectJAutoProxy.class, Aspect.class, Advice.class })
@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
public class AopAutoConfiguration {

   @Configuration
   @EnableAspectJAutoProxy(proxyTargetClass = false)
   @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = true)
   public static class JdkDynamicAutoProxyConfiguration {

   }

   @Configuration
   @EnableAspectJAutoProxy(proxyTargetClass = true)
   @ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = false)
   public static class CglibAutoProxyConfiguration {

   }

}

继续跟进 @EnableAspectJAutoProxy

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {.....}

最后可以跟到
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, Object source) {
   return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

上述代码可以看到注册了一个切面相关BeanDefinition,正是上面提到的类:
AnnotationAwareAspectJAutoProxyCreator
这里只是创建BeanDefinition,并没有实例化和初始化该对象。那什么时候会触发呢?
该类继承的顶层接口为 BeanPostProcessor。BeanPostProcessor实现类会提前初始化,在自动装配解析完成之后,直接实例化,不像普通bean一样


2: 扫描容器中的切面,创建PointcutAdvisor对象

这个过程出现在AnnotationAwareAspectJAutoProxyCreator的postProcessBeforeInstantiation方法中,在springboot创建bean的实例化bean之前被执行

protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
   ........
   try {
      // 遍历postprocessor,执行postProcessBeforeInstantiation方法
      Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
      if (bean != null) {
         return bean;
      }
   }
   catch (Throwable ex) {
      throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
            "BeanPostProcessor before instantiation of bean failed", ex);
   }

   //开始正式创建bean
   Object beanInstance = doCreateBean(beanName, mbdToUse, args);
   .......
}

跟进一下resolveBeforeInstantiation方法

protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
  .........
   bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
   .........
}

protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
   //遍历所有的后处理器,执行其postProcessBeforeInstantiation方法
   for (BeanPostProcessor bp : getBeanPostProcessors()) {
      if (bp instanceof InstantiationAwareBeanPostProcessor) {
         InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
         Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
         if (result != null) {
            return result;
         }
      }
   }
   return null;
}

我们可以看到后处理器集合中包含了AnnotationAwareAspectJAutoProxyCreator
在这里插入图片描述
下面来详细看看AnnotationAwareAspectJAutoProxyCreator中postProcessBeforeInstantiation做了什么

@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
			//advisedBeans用于存储不可代理的bean,如果包含直接返回
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			//判断当前bean是否可以被代理,然后存入advisedBeans
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				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.
		//到这里说明该bean可以被代理,所以去获取自定义目标类,如果没有定义,则跳过。
		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;
	}

来看一下判定 bean 是否被代理的方法依据:

@Override
protected boolean isInfrastructureClass(Class<?> beanClass) {
	return (super.isInfrastructureClass(beanClass) ||
			(this.aspectJAdvisorFactory != null && this.aspectJAdvisorFactory.isAspect(beanClass)));
}


private boolean hasAspectAnnotation(Class<?> clazz) {
	//判定当前类是否有 Aspect 注解,如果有,则不能被代理
	return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
}


protected boolean isInfrastructureClass(Class<?> beanClass) {
	//判定当前bean是否是 Advice、Pointcut、Advisor、AopInfrastructureBean等子类或实现类,如果是,则不能被代理
	boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
			Pointcut.class.isAssignableFrom(beanClass) ||
			Advisor.class.isAssignableFrom(beanClass) ||
			AopInfrastructureBean.class.isAssignableFrom(beanClass);
	if (retVal && logger.isTraceEnabled()) {
		logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
	}
	return retVal;
}

重点来看 shouldSkip方法:

@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
	// TODO: Consider optimization by caching the list of the aspect names
	//获取所有的候选顾问类 Advisor
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	for (Advisor advisor : candidateAdvisors) {
		if (advisor instanceof AspectJPointcutAdvisor &&
				((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
			return true;
		}
	}
	return super.shouldSkip(beanClass, beanName);
}

上述代码通过findCandidateAdvisors()方法来获取所有的候选 advisor:

@Override
	protected List<Advisor> findCandidateAdvisors() {
		// Add all the Spring advisors found according to superclass rules.
		//获得 Advisor 实现类
		List<Advisor> advisors = super.findCandidateAdvisors();
		// Build Advisors for all AspectJ aspects in the bean factory.
		//将@Aspect注解类, 解析成Advisor 
		if (this.aspectJAdvisorsBuilder != null) {
			advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
		}
		return advisors;
	}

继续跟进buildAspectJAdvisors方法,会触发
ReflectiveAspectJAdvisorFactory中的getAdvisors方法:

@Override
	public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
		//从 aspectMetadata 中获取 Aspect()标注的类 class对象
		Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
		//获取Aspect()标注的类名
		String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
		validate(aspectClass);

		// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
		// so that it will only instantiate once.
		MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
				new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

		List<Advisor> advisors = new LinkedList<>();
		//遍历该类所有方法,根据方法判断是否能获取到对应 pointCut,如果有,则生成 advisor 对象
		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.
		//获取 @DeclareParents 注解修饰的属性(并不常用)
		for (Field field : aspectClass.getDeclaredFields()) {
			Advisor advisor = getDeclareParentsAdvisor(field);
			if (advisor != null) {
				advisors.add(advisor);
			}
		}

		return advisors;
	}

继续来看getAdvisor方法:

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

		validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
		//根据候选方法名,来获取对应的 pointCut
		AspectJExpressionPointcut expressionPointcut = getPointcut(
				candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
		if (expressionPointcut == null) {
			return null;
		}
		//如果能获取到 pointCut,则将切点表达式 expressionPointcut、当前
		对象ReflectiveAspectJAdvisorFactory、 方法名等包装成 advisor 对象
		return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
				this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
	}

	}

	protected static AspectJAnnotation<?> findAspectJAnnotationOnMethod(Method method) {
		//定义class对象数组,如果方法中有以下注解中任何一种,则返回该注解
		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;
	}

InstantiationModelAwarePointcutAdvisorImpl的构造方法会触发构造通知对象:

public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
			MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
		//......
		//根据注解类型,匹配对应的通知类型
		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());
				}
			//异常通知
			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);
		}

		//......
	}

可以看到,根据@Aspect类中方法的注解类型,生成对应的advice,并通过通知的构造方法,将通知增强方法,切面表达式传入到通知当中。
从这里可以看到例子中的两个增强逻辑对应生成了两个advisor被缓存起来了,其中的advice类也分别是BeforeAdvice和AfterAdvice
在这里插入图片描述
到这里InstantiationModelAwarePointcutAdvisorImpl对象构造完毕。


3: 生成代理类

这个过程发生在初始化之后,这也是spring最后一个后处理器拓展接口

protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) {
    //执行postProcessBeforeInitialization逻辑
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
   }

    //初始化
   try {
      invokeInitMethods(beanName, wrappedBean, mbd);
   }
    //执行postProcessAfterInitialization逻辑
   if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
   }
   return wrappedBean;
}


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) {
   if (beanName != null && 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;
   }

   // 如果有合适的advisor就使用代理类
   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;
}


protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
   List<Advisor> candidateAdvisors = findCandidateAdvisors();
   //对所有的advisor进行筛选
   List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
   extendAdvisors(eligibleAdvisors);
   if (!eligibleAdvisors.isEmpty()) {
      eligibleAdvisors = sortAdvisors(eligibleAdvisors);
   }
   return eligibleAdvisors;
}

我们可以看到之前定义的两个增强逻辑被筛选了出来
在这里插入图片描述
然后就是生成代理类

protected Object createProxy(
      Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {

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

   ProxyFactory proxyFactory = new ProxyFactory();
   proxyFactory.copyFrom(this);

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

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

   proxyFactory.setFrozen(this.freezeProxy);
   if (advisorsPreFiltered()) {
      proxyFactory.setPreFiltered(true);
   }
    //生成代理类
   return proxyFactory.getProxy(getProxyClassLoader());
}

跟踪代码,这里可以看到Springboot中默认的动态代理方式为JDK动态代理hasNoUserSuppliedProxyInterfaces表明只要类有实现一定的接口就会使用JDK动态代理方式
CGLIB动态代理适用于没有实现接口的类进行动态代理,它使用的是继承的方式

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

到这里,AOP创建动态代理对象的逻辑已经完成了,但是我们并没有看出来增强的逻辑是怎么加入到动态代理类中的
这里先来复习一下Java中动态代理实现的过程,自定义一个handler实现InvicationHandler,其中包含委托类实例,实现一个接口方法invoke(),其主要用于写增强逻辑,并且用反射的方法实现原方法

public class StuInvocationHandler<T> implements InvocationHandler {
   //invocationHandler持有的被代理对象
    T target;
   
    public StuInvocationHandler(T target) {
       this.target = target;
    }
   
    /**
     * proxy:代表动态代理对象
     * method:代表正在执行的方法
     * args:代表调用目标方法时传入的实参
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("代理执行" +method.getName() + "方法");
     */  
        //代理过程中插入监测方法,计算该方法耗时
        MonitorUtil.start();
        Object result = method.invoke(target, args);
        MonitorUtil.finish(method.getName());
        return result;
    }
}
 
public static void main(String[] args) {
       
        //创建一个实例对象,这个对象是被代理的对象
        Person zhangsan = new Student("张三");
       
        //创建一个与代理对象相关联的InvocationHandler
        InvocationHandler stuHandler = new StuInvocationHandler<Person>(zhangsan);
       
        //创建一个代理对象stuProxy来代理zhangsan,代理对象的每个执行方法都会替换执行Invocation中的invoke方法
        Person stuProxy = (Person) Proxy.newProxyInstance(Person.class.getClassLoader(), new Class<?>[]{Person.class}, stuHandler)//代理执行上交班费的方法
        stuProxy.giveMoney();
}

我们再来看看spring中JDK动态代理类的实现,从getProxy方法中可以看到,spring同样也是使用的
Proxy.newProxyInstance(classLoader, proxiedInterfaces, this)方法,传入相同类型的三个参数

public Object getProxy(ClassLoader classLoader) {
   if (logger.isDebugEnabled()) {
      logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
   }
   Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
   findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
   return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}

重点就是这个invoke方法,它串联起了各个advisor的增强逻辑,从注释就可以看到,这个invoke也是实现的InvocationHandler.invoke方法,

/**
 * Implementation of {@code InvocationHandler.invoke}.
 */
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
   ............
      // 获取该方法的advisor拦截链
      List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

      // Check whether we have any advice. If we don't, we can fallback 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 {
         // 创建一个启动项
         invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
         // 启动项开始执行拦截链
         retVal = invocation.proceed();
      }
      .......
   }
}

这里重点来看看启动项ReflectiveMethodInvocation.proceed()方法,其中interceptorsAndDynamicMethodMatchers数据结构存储的就是该method适用的advisor的集合,整个执行过程是一个遍历拦截链,递归的过程,所谓的拦截链就是advisor的集合,只不过是按照before,after顺序排列好的

public Object proceed() throws Throwable {
   // 如果拦截链执行到了最后,则反射执行method原本的逻辑
   if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
      return invokeJoinpoint();
   }

   Object interceptorOrInterceptionAdvice =
         this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
   if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
      // Evaluate dynamic method matcher here: static part will already have
      // been evaluated and found to match.
      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);
   }
}

(1) 如果拦截链执行完,反射执行method自身的逻辑,
invokeJoinpoint()方法

public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
      throws Throwable {

   // 反射执行method方法
   ReflectionUtils.makeAccessible(method);
   return method.invoke(target, args);
 
}

(2) 遍历拦截链,执行每个advisor的增强逻辑
BeforeAdvice的执行

public class MethodBeforeAdviceInterceptor implements MethodInterceptor, Serializable {
........
   public Object invoke(MethodInvocation mi) throws Throwable {
       //先执行before的逻辑
      this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis() );
      //递归向下传递Invocation对象
      return mi.proceed();
   }
.........
}

AfterAdvice的执行,这里非常巧妙的使用finally,后置执行增强逻辑

public class AspectJAfterAdvice extends AbstractAspectJAdvice
      implements MethodInterceptor, AfterAdvice, Serializable {
........
   public Object invoke(MethodInvocation mi) throws Throwable {
      try {
          //先向下递归传递
         return mi.proceed();
      }
      finally {
          //执行after的增强逻辑
         invokeAdviceMethod(getJoinPointMatch(), null, null);
      }
   }
   .......
}

这样看是不是特别清楚了

画图来表示一下,假如现在有一个拦截链如图所示,2个before,2个after

在这里插入图片描述
那么根据拦截链的执行逻辑,其中advisor的增强逻辑的执行顺序为
在这里插入图片描述
JDK动态代理的方法就是这样被增强的


所以,总结来说,Spring的AOP本质就是动态代理,它的巧妙之处就在于将增强的逻辑封装成了拦截器,实现了一个拦截链,在invoke时,使用拦截器链增强方法

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值