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。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值