当前位置: 首页 > news >正文

SpringBoot AOP 源码解析

文章目录

  • 一、AOP 代码示例
    • 1. 准备注解和目标类
    • 2. 定义 Aspect
    • 3. 结论
  • 二、源码
    • 1. AOP 实现核心类
    • 2. 代理类的创建流程
      • 2.1 核心类 AbstractAutoProxyCreator
      • 2.2 AbstractAutoProxyCreator#postProcessBeforeInstantiation
      • 2.3 AspectJAwareAdvisorAutoProxyCreator#shouldSkip
      • 2.4 aspectJAdvisorsBuilder#buildAspectJAdvisors
      • 2.5 advisorFactory#getAdvisors
      • 2.6 AbstractAutoProxyCreator#postProcessAfterInitialization
      • 2.7 AbstractAutoProxyCreator#wrapIfNecessary
      • 2.8 添加 ExposeInvocationInterceptor
      • 2.9 创建代理对象 createProxy()
      • 2.10 ProxyFactory#getProxy
      • 2.11 CGLIB 代理类
      • 2.12 获取拦截器 getCallbacks
    • 3. Aop自动配置
      • 3.1 `AopAutoConfiguration` 源码
      • 3.2 `@EnableAspectJAutoProxy`
      • 3.3 AspectJAutoProxyRegistrar
      • 3.4 注册
    • 4. AOP 执行流程
      • 4.1 拦截器 DynamicAdvisedInterceptor
      • 4.2 方法执行 proceed
    • 总结
      • ExposeInvocationInterceptor


一、AOP 代码示例

1. 准备注解和目标类

/**
 * @author zhuRuiBo
 * @date 2025/2/21 11:22
 */
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Log {

    String value() default "";
}

@Slf4j
@RestController
@RequestMapping("/aop")
public class AopDemoController {

	/**
     * 切点
     */
    @Log("s1LogAnno")
    @GetMapping("s1")
    public String s1() {
        log.info("s1 ---");
        return "ok";
    }
}

2. 定义 Aspect

定义两个 Aspect, 一个 Around Aspect, 一个是分离(Before, After, AfterReturn, AfterThrowing)的 Aspect

/**
 * around Aspect
 * @author zhuRuiBo
 * @date 2025/2/21 11:25
 */
@Slf4j
@Component
@Aspect
public class LogAroundAspect {

    @Pointcut("@annotation(com.zrb.aop.demo.Log)")
    public void pointcut(){}

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        log.info("around - before: {}", joinPoint.getSignature().getName());
        Object result = joinPoint.proceed();
        log.info("around - after: {}", joinPoint.getSignature().getName());
        return result;
    }
}
@Slf4j
@Component
@Aspect
public class LogSeparateAspect {

    @Pointcut("@annotation(com.zrb.aop.demo.Log)")
    public void pointcut(){}

    @Before("pointcut()")
    public void before(){
        log.info("LogSeparateAspect before");
    }

    @After("pointcut()")
    public void after() {
        log.info("LogSeparateAspect after");
    }

    @AfterReturning("pointcut()")
    public void afterReturning() {
        log.info("LogSeparateAspect afterReturning");
    }

    @AfterThrowing("pointcut()")
    public void afterThrowing() {
        log.info("LogSeparateAspect afterThrowing");
    }
}

3. 结论

2025-02-26 14:12:39.843  INFO 67047 --- [io-10010-exec-1] com.zrb.aop.demo.LogAroundAspect         : around - before: s1
2025-02-26 14:12:39.843  INFO 67047 --- [io-10010-exec-1] com.zrb.aop.demo.LogSeparateAspect       : LogSeparateAspect before
2025-02-26 14:12:39.850  INFO 67047 --- [io-10010-exec-1] com.zrb.aop.demo.AopDemoController       : s1 ---
2025-02-26 14:12:39.850  INFO 67047 --- [io-10010-exec-1] com.zrb.aop.demo.LogSeparateAspect       : LogSeparateAspect afterReturning
2025-02-26 14:12:39.850  INFO 67047 --- [io-10010-exec-1] com.zrb.aop.demo.LogSeparateAspect       : LogSeparateAspect after
2025-02-26 14:12:39.850  INFO 67047 --- [io-10010-exec-1] com.zrb.aop.demo.LogAroundAspect         : around - after: s1

二、源码

此处源码参考 springboot-2.7.3 版本
本篇源码只解析 Aop 的核心, 直接跳过 spring 的生命周期流程

1. AOP 实现核心类

  1. AbstractAutoProxyCreator: 创建代理的核心类, 代理对象就在 wrapIfNecessary 方法中创建
  2. @EnableAspectJAutoProxy 开启 Aspect 自动配置,或许在老版本中我们还需要手动添加这个注解, 但是在 2.7.3 版本中,已经不需要手动引入这个注解了
  3. AopAutoConfiguration : Aop 自动配置类
  4. AdvisorAdvice:Advisor 中包含了一个 Advice, 而每一个 Aop 注解(@Around,@Before, @After 等等)都会被包装成为一个 Advice, 最终也是通过 Advice 去执行目标方法

2. 代理类的创建流程

2.1 核心类 AbstractAutoProxyCreator

/**
 * 实现了 SmartInstantiationAwareBeanPostProcessor, 所以在 Bean 的生命周期中会执行该类的
 * postProcessBeforeInstantiation 和 postProcessAfterInstantiation
 * 这里直接说结论: 代理一般是在 postProcessAfterInstantiation 中创建的
 * 	postProcessBeforeInstantiation 中也可能会创建,但是一般不会在这个方法中创建
 * 扩展:SmartInstantiationAwareBeanPostProcessor 本身还有一个 getEarlyBeanReference 的方法, 这个方法被三级缓存所引用
 * 目的是为了方便随时从三级缓存中创建代理,因此代理对象也可能在三级缓存中直接创建
 */
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
		implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

2.2 AbstractAutoProxyCreator#postProcessBeforeInstantiation

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

	if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
		if (this.advisedBeans.containsKey(cacheKey)) {
			return null;
		}
		// 注意这个 shouldSkip 及其重要,实现类 AspectJAwareAdvisorAutoProxyCreator 里面会创建 Advisor
		// 然后 Advisor 构造器中会创建 Advice
		if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
			this.advisedBeans.put(cacheKey, Boolean.FALSE);
			return null;
		}
	}
	// 一般来讲这个地方获取到的是 null, 因此一般不会在这个地方就创建代理类
	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;
}

2.3 AspectJAwareAdvisorAutoProxyCreator#shouldSkip

@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
	// TODO: Consider optimization by caching the list of the aspect names
	// 获取 ioc 中手动注入的 Advisor, 在 AnnotationAwareAspectJAutoProxyCreator 中会创建 Aspect 中的 Advisor
	// 至于为什么会是 AnnotationAwareAspectJAutoProxyCreator 可以参考第二章
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	for (Advisor advisor : candidateAdvisors) {
		if (advisor instanceof AspectJPointcutAdvisor &&
				((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
			return true;
		}
	}
	return super.shouldSkip(beanClass, beanName);
}

/**
 * AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
 */
@Override
protected List<Advisor> findCandidateAdvisors() {
	// Add all the Spring advisors found according to superclass rules.
	// super.findCandidateAdvisors() 是获取 spring 中显示加入的 Advisor
	List<Advisor> advisors = super.findCandidateAdvisors();
	// Build Advisors for all AspectJ aspects in the bean factory.
	if (this.aspectJAdvisorsBuilder != null) {
		// buildAspectJAdvisors() 将 Aspect 类,构建成 Advisor
		advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
	}
	return advisors;
}

2.4 aspectJAdvisorsBuilder#buildAspectJAdvisors

将 Aspect 构建成 Advisor

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

	if (aspectNames == null) {
		synchronized (this) {
			aspectNames = this.aspectBeanNames;
			// 只会初始化一次
			if (aspectNames == null) {
				List<Advisor> advisors = new ArrayList<>();
				aspectNames = new ArrayList<>();
				// 获取所有的 beanNames
				String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
						this.beanFactory, Object.class, true, false);
				for (String beanName : beanNames) {
					// 判断是否符合条件的 beanName, 当前一直返回 true
					if (!isEligibleBean(beanName)) {
						continue;
					}
					// We must be careful not to instantiate beans eagerly as in this case they
					// would be cached by the Spring container but would not have been weaved.
					Class<?> beanType = this.beanFactory.getType(beanName, false);
					if (beanType == null) {
						continue;
					}
					// 判断当前 bean 是否是一个 Aspect
					// 很简单,通过判断该类上是否注有 @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);
							// 通过 advisorFactory 创建 advisor
							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);
						}
						...
					}
				}
				this.aspectBeanNames = aspectNames;
				return advisors;
			}
		}
	}
	...
	return advisors;
}

2.5 advisorFactory#getAdvisors

/**
 * advisorFactory#getAdvisors
 */
@Override
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
	Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
	String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
	validate(aspectClass);

	...
	MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
			new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

	List<Advisor> advisors = new ArrayList<>();
	// getAdvisorMethods 是获取了除了 @Pointcut 之外的所有的方法
	for (Method method : getAdvisorMethods(aspectClass)) {
		...
		// getAdvisor 中,如果没有任何的注解将会返回 null
		// 默认 Advisor 实现类为 InstantiationModelAwarePointcutAdvisorImpl, 构造器中会创建 Advise
		Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, 0, aspectName);
		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());
	AspectJExpressionPointcut expressionPointcut = getPointcut(
			candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
	if (expressionPointcut == null) {
		return null;
	}
	// 默认的 Advisor 实现类为 InstantiationModelAwarePointcutAdvisorImpl
	return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
			this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}

2.6 AbstractAutoProxyCreator#postProcessAfterInitialization

// AbstractAutoProxyCreator#postProcessAfterInitialization
@Override
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
	if (bean != null) {
		Object cacheKey = getCacheKey(bean.getClass(), beanName);
		if (this.earlyProxyReferences.remove(cacheKey) != bean) {
			// 核心方法 wrapIfNecessary
			// 另外三级缓存中存放的 lambda 也会调用这个方法 
			return wrapIfNecessary(bean, beanName, cacheKey);
		}
	}
	return bean;
}

2.7 AbstractAutoProxyCreator#wrapIfNecessary

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. 
	// 创建代理对象,如果我们有 Advice 的话
	// 获取所有的 Advisor, 如果存在 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;
}

2.8 添加 ExposeInvocationInterceptor

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

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

/**
 * AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
 */
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
	// 获取所有的 Advisor
	List<Advisor> candidateAdvisors = findCandidateAdvisors();
	List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
	// 添加一个头部的 Advisor: 
	extendAdvisors(eligibleAdvisors);
	if (!eligibleAdvisors.isEmpty()) {
		eligibleAdvisors = sortAdvisors(eligibleAdvisors);
	}
	return eligibleAdvisors;
}

/* 
 * AspectJAwareAdvisorAutoProxyCreator#extendAdvisors
 */
@Override
protected void extendAdvisors(List<Advisor> candidateAdvisors) {
	AspectJProxyUtils.makeAdvisorChainAspectJCapableIfNecessary(candidateAdvisors);
}

/**
 * AspectJProxyUtils#makeAdvisorChainAspectJCapableIfNecessary
 */
public static boolean makeAdvisorChainAspectJCapableIfNecessary(List<Advisor> advisors) {
	// Don't add advisors to an empty list; may indicate that proxying is just not required
	if (!advisors.isEmpty()) {
		// 在 Advisor 上添加一个 ExposeInvocationInterceptor.ADVISOR
		if (foundAspectJAdvice && !advisors.contains(ExposeInvocationInterceptor.ADVISOR)) {
			advisors.add(0, ExposeInvocationInterceptor.ADVISOR);
			return true;
		}
	}
	return false;
}

2.9 创建代理对象 createProxy()

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 创建代理的时候定制化
	ProxyFactory proxyFactory = new ProxyFactory();
	proxyFactory.copyFrom(this);
	...
	// 获取 Advisors
	Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
	proxyFactory.addAdvisors(advisors);
	proxyFactory.setTargetSource(targetSource);
	// 钩子, 可以定制化 proxyFactory
	customizeProxyFactory(proxyFactory);
	...
	// 通过 proxyFactory 获取代理对象
	return proxyFactory.getProxy(classLoader);
}

2.10 ProxyFactory#getProxy

/**
 * ProxyFactory#getProxy
 */
public Object getProxy(@Nullable ClassLoader classLoader) {
	return createAopProxy().getProxy(classLoader);
}

/**
 * createAopProxy
 */
protected final synchronized AopProxy createAopProxy() {
	if (!this.active) {
		activate();
	}
	return getAopProxyFactory().createAopProxy(this);
}

/**
 * createAopProxy()
 * 总结:
 * 1. 如果没有开启“类”类型的代理, 直接使用 JDK 的代理
 * 2. 如果目标类是一个接口, 一个已经被代理过的类, 或者是一个 lambda 表达式, 都是用 JDK 的代理, 否则是用 CGLIB
 */
 @Override
public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
	...
	// 这个判断, 简单来说就是开启了类类型的代理, 如果没有开启, 直接使用 JDK 的代理
	if (!NativeDetector.inNativeImage() &&
				(config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config))) {
	// 如果目标类是一个接口, 一个已经被代理过的类, 或者是一个 lambda 表达式, 都是用 JDK 的代理, 否则是用 CGLIB
		if (targetClass.isInterface() || Proxy.isProxyClass(targetClass) || ClassUtils.isLambdaClass(targetClass)) {
			return new JdkDynamicAopProxy(config);
		}
		return new ObjenesisCglibAopProxy(config);
	}
	else {
		return new JdkDynamicAopProxy(config);
	}
}

2.11 CGLIB 代理类

下面的代码, 需要知道 CGLIB 如何使用

@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
	try {
		... 
		// Configure CGLIB Enhancer...
		// 创建 Enhancer
		Enhancer enhancer = createEnhancer();
		...
		// 获取 callback
		Callback[] callbacks = getCallbacks(rootClass);
		...
		// 将 callback 设置到 enhancer 上
		return createProxyClassAndInstance(enhancer, callbacks);
	}
	...
}

2.12 获取拦截器 getCallbacks

private Callback[] getCallbacks(Class<?> rootClass) throws Exception {
	...
	// Choose an "aop" interceptor (used for AOP calls).
	// Aop 的默认 Callback
	Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);
	...
	return callbacks;
}

3. Aop自动配置

查看 Springboot 的自动配置类中与 Aop 相关的, 可以看到 springboot 引入了一个 AopAutoConfiguration
在这里插入图片描述

3.1 AopAutoConfiguration 源码

	/**
	 * spring.aop.proxy-target-class 指的是是否自动代理“类”类型的
	 * 可以看到无论如何都会引入 @EnableAspectJAutoProxy
	 */
	@AutoConfiguration
	@ConditionalOnProperty(prefix = "spring.aop", name = "auto", havingValue = "true", matchIfMissing = true)
	public class AopAutoConfiguration {
	
		@Configuration(proxyBeanMethods = false)
		@ConditionalOnClass(Advice.class)
		static class AspectJAutoProxyingConfiguration {
	
			
			@Configuration(proxyBeanMethods = false)
			@EnableAspectJAutoProxy(proxyTargetClass = false)
			@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false")
			static class JdkDynamicAutoProxyConfiguration {
	
			}
	
			@Configuration(proxyBeanMethods = false)
			@EnableAspectJAutoProxy(proxyTargetClass = true)
			@ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true",
					matchIfMissing = true)
			static class CglibAutoProxyConfiguration {
	
			}
	
		}
		...
	}

3.2 @EnableAspectJAutoProxy

/**
 * 引入了一个 AspectJAutoProxyRegistrar 类
 */
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {

	
	boolean proxyTargetClass() default false;

	boolean exposeProxy() default false;

}

3.3 AspectJAutoProxyRegistrar

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {

	/**
	 * 注册 Aop 需要的类
	 */
	@Override
	public void registerBeanDefinitions(
			AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
		// 注册 AbstractAutoProxyCreator 的具体子类
		AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);

		AnnotationAttributes enableAspectJAutoProxy =
				AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
		if (enableAspectJAutoProxy != null) {
			if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
				AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
			}
			if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
				AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
			}
		}
	}

}

3.4 注册

@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
	return registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry, null);
}

/**
 * 由此可见 @EnableAspectJAutoProxy 注册的 AbstractAutoProxyCreator 为 AnnotationAwareAspectJAutoProxyCreator
 */
@Nullable
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
		BeanDefinitionRegistry registry, @Nullable Object source) {

	return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}

4. AOP 执行流程

这里只研究 CGLIB 的代理

4.1 拦截器 DynamicAdvisedInterceptor

从源码 1 可知,代理类的拦截器是 DynamicAdvisedInterceptor,当执行目标方法的时候会执行到该类的 interceptor 方法中

@Override
@Nullable
	public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
		Object oldProxy = null;
		boolean setProxyContext = false;
		Object target = null;
		TargetSource targetSource = this.advised.getTargetSource();
		try {
			if (this.advised.exposeProxy) {
				// Make invocation available if necessary.
				oldProxy = AopContext.setCurrentProxy(proxy);
				setProxyContext = true;
			}
			// 这行代码也很重要, advised 就是之前的 ProxyFactory, 这里面将每个 Advisor 里面的 Advise 取出来组成一个链
			// 第一个 Advise 是 ExposeInvocationInterceptor#ADVISOR
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
			Object retVal;
			// Check whether we only have one InvokerInterceptor: that is,
			// no real advice, but just reflective invocation of the target.
			if (chain.isEmpty() && CglibMethodInvocation.isMethodProxyCompatible(method)) {
				...
			}
			else {
				// We need to create a method invocation...
				// 创建一个 CglibMethodInvocation, 执行目标方法
				// CglibMethodInvocation 是贯穿整个 aop 上下文的一个对象
				retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
			}
			retVal = processReturnType(proxy, target, method, retVal);
			return retVal;
		}
		finally {
			if (target != null && !targetSource.isStatic()) {
				targetSource.releaseTarget(target);
			}
			if (setProxyContext) {
				// Restore old proxy.
				AopContext.setCurrentProxy(oldProxy);
			}
		}
	}

4.2 方法执行 proceed

是一个链式的执行方式,与 SpringSecurity 的过滤器链一样

@Override
@Nullable
public Object proceed() throws Throwable {
	// We start with an index of -1 and increment early.
	if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
	    // 开始执行目标方法
		return invokeJoinpoint();
	}

	// 找到当前的 Advice
	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;
		Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
		if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
			// dm.interceptor 其实就是各个 Advise
			// 比如说 @Around 就是 AspectJAroundAdvice, @Before 就是 MethodBeforeAdviceInterceptor
			// 这里把自身传递下去, interceptor执行 proceed() 就会回到当前方法, 当所有的 Advice 执行完成之后, 就会执行目标方法, 然后将返回值依次返回给 Advise
			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);
	}
}

总结

ExposeInvocationInterceptor

它的主要作用是将当前的 MethodInvocation 对象暴露给后续的拦截器或切面,以便在 AOP 链中的任何地方都可以访问当前的调用上下文。在自定义拦截器中,可以通过 ExposeInvocationInterceptor.currentInvocation() 获取当前的 MethodInvocation

相关文章:

  • Selenium 不同语言绑定版本的官方操作文档获取途径(科学上网)
  • WPF12-MVVM
  • 禹神:一小时快速上手Electron,前端Electron开发教程,笔记。一篇文章入门Electron
  • 牛客刷题自留-深度学习
  • 【cv】vs2022配置opencv
  • flutter 局部刷新控件Selector源码实现原理
  • Spring之Bean的生命周期过程中调用的方法
  • MySQL -操作
  • 12个大语言模型平台对比测试-搜索视角
  • 网络安全(黑客技术)一2025年自学入门手册_合天网安-零基础系统学习网络安全教程下载
  • 使用MATLAB结合EasySpin进行ESR模拟的详细步骤及示例代码
  • 达梦数据库授权给某个用户查询其他指定用户下所有表的权限
  • OSPF BIT 类型说明
  • labview中VISA串口出现异常的解决方案
  • 基于element-ui封装月日选择器(不包含年)
  • Vue.js响应式基础
  • 设计模式 简单汇总
  • DeepSeek引发的全栈开发范式革命?
  • 复用时钟 重映射(Remap)
  • DeepSeek 助力 Vue3 开发:打造丝滑的页眉(Header)
  • 购物网站开发价格/网站优化seo教程
  • 摄影做网站/郑州做网络营销渠道
  • 自己做的网站突然打不开/网络推广企业
  • 电影网站做淘宝联盟/长沙的seo网络公司
  • node 做的大型网站/最近的新闻大事
  • wordpress可以做门户网站/找关键词的方法与技巧