spring aop运行时执行栈分析
问题:
1.spring aop的切面方法是怎样被添加的?
2.spring aop的切面方法是怎样被执行的?
spring aop的切面方法是怎样被添加的?
首先定义3个MethodInterceptor Advisor :
- ExposeInvocationInterceptor【spring默认添加的,why?】
- ScfMethodLogger【通过继承StaticMethodMatcherPointcutAdvisor】
- AspectJAroundAdvice【aspectJAdviceMethod是LoggerAspect】
spring启动时,首先会最大努力寻找所有的bean定义,包括上面的Advisor定义。然后spring容器对bd进行实例化和初始化,初始化后,容器会执行代理proxy配置,此时就会把上面的advisor添加到执行chain里。
代码的参考位置:
org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip
org.springframework.aop.framework.autoproxy.BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
spring aop的切面方法是怎样被执行的?
调用栈如下:
org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor#intercept
org.springframework.aop.framework.DefaultAdvisorChainFactory#getInterceptorsAndDynamicInterceptionAdvice
org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation(this$123)#proceed
org.aopalliance.intercept.MethodInterceptor#invoke(this$123)【MethodInterceptor:ExposeInvocationInterceptor】
org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation(this$123)#proceed
org.aopalliance.intercept.MethodInterceptor#invoke(this$123)【MethodInterceptor:ScfMethodLogger】
org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation(this$123)#lllll
org.aopalliance.intercept.MethodInterceptor#invoke(this$123)【MethodInterceptor:AspectJAroundAdvice】
org.springframework.aop.aspectj.AspectJAroundAdvice#lazyGetProceedingJoinPoint【封装this$123为ProceedingJoinPoint,即MethodInvocationProceedingJoinPoint$10986】
org.springframework.aop.aspectj.AbstractAspectJAdvice#invokeAdviceMethod(org.aspectj.lang.JoinPoint, org.aspectj.weaver.tools.JoinPointMatch, java.lang.Object, java.lang.Throwable)
org.springframework.aop.aspectj.AbstractAspectJAdvice#argBinding
org.springframework.aop.aspectj.AbstractAspectJAdvice#invokeAdviceMethodWithGivenArgs
java.lang.reflect.Method#invoke【this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs);】
com.zhuanzhuan.hunter.zeus.po.aspect.LoggerAspect#doAround【参数是MethodInvocationProceedingJoinPoint$10986】
org.aspectj.lang.ProceedingJoinPoint#proceed()【ProceedingJoinPoint:MethodInvocationProceedingJoinPoint$10986】
this.methodInvocation.invocableClone()【this.methodInvocation=this$123,return CglibMethodInvocation$14252】
CglibMethodInvocation$14252.proceed
org.springframework.aop.framework.ReflectiveMethodInvocation#invokeJoinpoint
org.springframework.aop.support.AopUtils#invokeJoinpointUsingReflection
real method

为什么要invocableClone?
public abstract org.aopalliance.intercept.MethodInvocation invocableClone()
Create a clone of this object. If cloning is done before proceed() is invoked on this object, proceed() can be invoked once per clone to invoke the joinpoint (and the rest of the advice chain) more than once.
Returns:
an invocable clone of this invocation. proceed() can be called once per clone.
其中一个效果就是,被clone的MethodInvocation对象可以再执行一次proceed,就可以实现多次调用joinpoint。