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 实现核心类
AbstractAutoProxyCreator:
创建代理的核心类, 代理对象就在wrapIfNecessary
方法中创建@EnableAspectJAutoProxy
开启 Aspect 自动配置,或许在老版本中我们还需要手动添加这个注解, 但是在 2.7.3 版本中,已经不需要手动引入这个注解了AopAutoConfiguration
: Aop 自动配置类Advisor
与Advice
: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