Spring AOP 源码探索 之 链式调用中的 ExposeInvocationInterceptor拦截器作用

文章目录

    • ExposeInvocationInterceptor
      • 示例代码
      • 源码分析
        • extendAdvisors
        • makeAdvisorChainAspectJCapableIfNecessary
      • 添加扩展拦截器的调用链
      • 作用示例
    • 总结
  • 相关学习路线
    • JAVA资深架构师成长路线->开源框架解读->Spring框架源码解读

ExposeInvocationInterceptor

从英文名字,顾名思义,暴露调用器的拦截器。
其就是起了暴露一个调用器作用的拦截器。

  • 1、那么其暴露了什么调用器?
  • 2、是如何暴露的,通过什么方法实现?
  • 3、暴露给谁?
  • 4、在什么时候起到拦截作用?

下面带着以上问题,通过示例代码来分析spring Aop源码

示例代码

Spring AOP 源码探索 之 示例代码

源码分析

extendAdvisors

在初始化完Bean,调用AbstractAutoProcxyCreator的后置处理方法postProcessAfterInitialization的时候,对adivisors进行了扩展,添加了ExposeInvocationInterceptor拦截器
Spring AOP 源码探索 之 链式调用中的 ExposeInvocationInterceptor拦截器作用_第1张图片

makeAdvisorChainAspectJCapableIfNecessary

实际添加了ExposeInvocationInterceptor拦截器的地方
作者英文注释:

/**
* Add special advisors if necessary to work with a proxy chain that contains AspectJ advisors.
* This will expose the current Spring AOP invocation (necessary for some AspectJ pointcut matching)
* and make available the current AspectJ JoinPoint. The call will have no effect if there are no
* AspectJ advisors in the advisor chain.
* @param advisors Advisors available
* @return {@code true} if any special {@link Advisor Advisors} were added, otherwise {@code false}.
*/

Spring AOP 源码探索 之 链式调用中的 ExposeInvocationInterceptor拦截器作用_第2张图片

添加扩展拦截器的调用链

方法栈图示
Spring AOP 源码探索 之 链式调用中的 ExposeInvocationInterceptor拦截器作用_第3张图片
完整方法栈

makeAdvisorChainAspectJCapableIfNecessary:44, AspectJProxyUtils (org.springframework.aop.aspectj)
extendAdvisors:97, AspectJAwareAdvisorAutoProxyCreator (org.springframework.aop.aspectj.autoproxy)
findEligibleAdvisors:90, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
getAdvicesAndAdvisorsForBean:70, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
wrapIfNecessary:346, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
postProcessAfterInitialization:298, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
applyBeanPostProcessorsAfterInitialization:421, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
initializeBean:1635, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
doCreateBean:553, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
createBean:481, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
getObject:312, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
doGetBean:308, AbstractBeanFactory (org.springframework.beans.factory.support)
getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
preInstantiateSingletons:761, DefaultListableBeanFactory (org.springframework.beans.factory.support)
finishBeanFactoryInitialization:867, AbstractApplicationContext (org.springframework.context.support)
refresh:543, AbstractApplicationContext (org.springframework.context.support)
<init>:84, AnnotationConfigApplicationContext (org.springframework.context.annotation)
main:11, SilasMainClass (org.silas)

作用示例

在代理对象调用方法时起作用。
Spring AOP 源码探索 之 方法栈及链式调用解读

调用链首先调用此ExposeInvocationInterceptor拦截器的invoke方法,将MethodInvocation mi 设置到
ThreadLocal invocation 里面
Spring AOP 源码探索 之 链式调用中的 ExposeInvocationInterceptor拦截器作用_第4张图片
以后置通知(@After)拦截器的invoke为例
org.springframework.aop.aspectj.AspectJAfterAdvice#invoke
Spring AOP 源码探索 之 链式调用中的 ExposeInvocationInterceptor拦截器作用_第5张图片
在调用通知方法invokeAdviceMethod的时候传了一个参,参数通过调用getJoinPointMatch()方法获得。
Spring AOP 源码探索 之 链式调用中的 ExposeInvocationInterceptor拦截器作用_第6张图片
看下getJoinPointMatch()方法源码
Spring AOP 源码探索 之 链式调用中的 ExposeInvocationInterceptor拦截器作用_第7张图片
ExposeInvocationInterceptor.currentInvocation()方法
从ThreadLocal invocation 里面取出了
前面通过ExposeInvocationInterceptor实例对象set进去的mi
Spring AOP 源码探索 之 链式调用中的 ExposeInvocationInterceptor拦截器作用_第8张图片

总结

那么从上面的AspectJAfterAdvice#invoke方法例子可以知道,ExposeInvocationInterceptor就是用来传递MethodInvocation的。在后续的任何下调用链环节,只要需要用到当前的MethodInvocation就通过ExposeInvocationInterceptor.currentInvocation()静态方法获得。

相关学习路线

JAVA资深架构师成长路线->开源框架解读->Spring框架源码解读

你可能感兴趣的:(AOP,Spring源码,开源框架)