文章目錄
- 一、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 ProxyProcessorSupportimplements 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 構造器中會創建 Adviceif (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 中顯示加入的 AdvisorList<Advisor> advisors = super.findCandidateAdvisors();// Build Advisors for all AspectJ aspects in the bean factory.if (this.aspectJAdvisorsBuilder != null) {// buildAspectJAdvisors() 將 Aspect 類,構建成 Advisoradvisors.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<>();// 獲取所有的 beanNamesString[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);for (String beanName : beanNames) {// 判斷是否符合條件的 beanName, 當前一直返回 trueif (!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 創建 advisorList<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, 構造器中會創建 AdviseAdvisor 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 實現類為 InstantiationModelAwarePointcutAdvisorImplreturn 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) {// 獲取所有的 AdvisorList<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 requiredif (!advisors.isEmpty()) {// 在 Advisor 上添加一個 ExposeInvocationInterceptor.ADVISORif (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);...// 獲取 AdvisorsAdvisor[] advisors = buildAdvisors(beanName, specificInterceptors);proxyFactory.addAdvisors(advisors);proxyFactory.setTargetSource(targetSource);// 鉤子, 可以定制化 proxyFactorycustomizeProxyFactory(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 的代理, 否則是用 CGLIBif (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...// 創建 EnhancerEnhancer enhancer = createEnhancer();...// 獲取 callbackCallback[] 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 的默認 CallbackCallback 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 需要的類*/@Overridepublic 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
@Nullablepublic 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#ADVISORList<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();}// 找到當前的 AdviceObject 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 執行完成之后, 就會執行目標方法, 然后將返回值依次返回給 Advisereturn 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