在线记录源码调试之@EnableAspectJAutoProxy与Spring AOP(三)调用被代理方法userServiceImpl.save(user)
测试用例1
连接点
@Component
public class UserServiceImpl implements UserService {@Overridepublic void save(UserInfo userInfo) {System.out.println("执行保存:"+userInfo.getName());}
}
测试用例2
切点pointCut、切面testAspect、前置通知methodBefore和后置通知methodAfter
@Aspect
@Component
public class TestAspect {@Pointcut("execution(* com.helloworld.service.impl.UserServiceImpl.*(..))")public void pointCut(){};@Before(value = "pointCut()")public void methodBefore(JoinPoint joinPoint) {String methodName = joinPoint.getSignature().getName();System.out.println("执行目标方法【"+methodName+"】的<前置通知>,入参"+ Arrays.asList(joinPoint.getArgs()));}@After(value = "pointCut()")public void methodAfter(JoinPoint joinPoint) {String methodName = joinPoint.getSignature().getName();System.out.println("执行目标方法【"+methodName+"】的<后置通知>,入参"+Arrays.asList(joinPoint.getArgs()));}
}
测试用例3
测试用例:启动引导类,新建spring容器对象AnnotationConfigApplicationContext
@Configuration
@ComponentScan
@EnableAspectJAutoProxy(proxyTargetClass = true)
public class DemoApplication {public static void main( String[] args ) {AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(DemoApplication.class);UserService userService = (UserService) ctx.getBean("userServiceImpl");UserInfo userInfo = (UserInfo) ctx.getBean("user_zhangsan");userService.save(userInfo);}
}
下面执行userServiceImpl的save方法,首先获取userServiceImpl的通知
将断点打到MethodBeforeAdviceInterceptor.MethodBeforeAdviceInterceptor()方法,则代码执行过程如下
代码块1:main
拦截
参数:args=[]
package com.helloworld;public class DemoApplication {public static void main( String[] args ) { //args=[];......userService.save(userInfo);"(1) 拦截""参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)""参数:args=com.helloworld.entity.UserInfo@2e9fda69,"}}
代码块2:intercept
获取拦截器和动态拦截通知
参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)
参数:args=com.helloworld.entity.UserInfo@2e9fda69,
package org.springframework.aop.framework;public class CglibAopProxy implements AopProxy{@Override@Nullablepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { //method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo);args=com.helloworld.entity.UserInfo@2e9fda69,;......List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); //Get the interception chain for this method.1-获取目标方法的拦截链 chain=org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6,org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect',org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,; "(2) 获取拦截器和动态拦截通知""参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)""参数:targetClass=class com.helloworld.service.impl.UserServiceImpl""Get the interception chain for this method.1-获取目标方法的拦截链 chain=org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6,org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect',org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,;"......}}
代码块3:getInterceptorsAndDynamicInterceptionAdvice
获取拦截器和动态拦截通知
参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)
参数:targetClass=class com.helloworld.service.impl.UserServiceImpl
package org.springframework.aop.framework;public class AdvisedSupport extends ProxyConfig implements Advised{public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) { //method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo);targetClass=class com.helloworld.service.impl.UserServiceImpl;......cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( // cached=org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6,org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect',org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,; this, method, targetClass);"(3) 获取拦截器和动态拦截通知""参数:config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false""参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)""参数:targetClass=class com.helloworld.service.impl.UserServiceImpl""cached=org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6,org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect',org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,;"......}}
代码块4:getInterceptorsAndDynamicInterceptionAdvice
获取拦截器
参数:config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor…
参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)
参数:targetClass=class com.helloworld.service.impl.UserServiceImpl
package org.springframework.aop.framework;public class DefaultAdvisorChainFactory implements AdvisorChainFactory{@Overridepublic List<Object> getInterceptorsAndDynamicInterceptionAdvice( //config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false;method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo);targetClass=class com.helloworld.service.impl.UserServiceImpl;Advised config, Method method, @Nullable Class<?> targetClass) {......MethodInterceptor[] interceptors = registry.getInterceptors(advisor); //将advisor转为MethodInterceptor interceptors=org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6,; interceptors=org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect',; interceptors=org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,; "(4) 获取拦截器""参数:advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON""将advisor转为MethodInterceptor interceptors=org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6,; interceptors=org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect',; interceptors=org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,;"......}}
代码块5:getInterceptors
获取拦截器
参数:advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.T…
package org.springframework.aop.framework.adapter;public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry{@Overridepublic MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { //advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON;......interceptors.add(adapter.getInterceptor(advisor)); //获取方法拦截器并放入到集合中返回"(5) 获取拦截器""参数:advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON""获取方法拦截器并放入到集合中返回"......}}
代码块6:getInterceptor
init
参数:advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.T…
package org.springframework.aop.framework.adapter;public class MethodBeforeAdviceAdapter implements AdvisorAdapter{@Overridepublic MethodInterceptor getInterceptor(Advisor advisor) { //advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON;......return new MethodBeforeAdviceInterceptor(advice); //通知类型匹配对应的拦截器"(6) init""参数:advice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect'""通知类型匹配对应的拦截器"}}
代码块7:MethodBeforeAdviceInterceptor()
创建前置通知拦截器对象
参数:advice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspe…
package org.springframework.aop.framework.adapter;public class MethodBeforeAdviceInterceptor implements MethodInterceptor{public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) { //advice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect';......this.advice = advice; // this.advice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect'; "(7) 创建前置通知拦截器对象""this.advice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect';"}}
小结:调用栈
下面执行userServiceImpl的save方法,首先获取userServiceImpl的通知
- *DemoApplication.main()
- *CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- *AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice()
- *DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()
- *DefaultAdvisorAdapterRegistry.getInterceptors()
- *MethodBeforeAdviceAdapter.getInterceptor()
- *MethodBeforeAdviceInterceptor.MethodBeforeAdviceInterceptor()
调用methodBefore前置通知
将断点打到TestAspect.methodBefore方法,则代码执行过程如下
代码块8:intercept
继续进行
参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)
参数:args=com.helloworld.entity.UserInfo@2e9fda69,
package org.springframework.aop.framework;public class CglibAopProxy implements AopProxy{@Override@Nullablepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { //method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo);args=com.helloworld.entity.UserInfo@2e9fda69,;......List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);"(2)"retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed(); //封装拦截器链并执行"(8) 继续进行""封装拦截器链并执行"......}}
代码块9:proceed
调用
package org.springframework.aop.framework;public class ReflectiveMethodInvocation implements ProxyMethodInvocation{@Override@Nullablepublic Object proceed() throws Throwable {......return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); //It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"(9) 调用""It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"......}}
代码块10:invoke
继续进行
package org.springframework.aop.interceptor;public class ExposeInvocationInterceptor implements MethodInterceptor{@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {......return mi.proceed(); //执行目标方法"(10) 继续进行""执行目标方法"......}}
代码块11:proceed
调用
package org.springframework.aop.framework;public class ReflectiveMethodInvocation implements ProxyMethodInvocation{@Override@Nullablepublic Object proceed() throws Throwable {......return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); //It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"(11) 调用""It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"......}}
代码块12:invoke
继续进行
package org.springframework.aop.aspectj;public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor{@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {......return mi.proceed(); //执行目标方法"(12) 继续进行""执行目标方法"......}}
代码块13:proceed
调用
package org.springframework.aop.framework;public class ReflectiveMethodInvocation implements ProxyMethodInvocation{@Override@Nullablepublic Object proceed() throws Throwable {......return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); //It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"(13) 调用""It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"......}}
代码块14:invoke
在此之前
package org.springframework.aop.framework.adapter;public class MethodBeforeAdviceInterceptor implements MethodInterceptor{@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); //执行拦截器before方法"(14) 在此之前""参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)""参数:args=com.helloworld.entity.UserInfo@2e9fda69,""执行拦截器before方法"......}}
代码块15:before
调用通知方法
参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)
参数:args=com.helloworld.entity.UserInfo@2e9fda69,
package org.springframework.aop.aspectj;public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice{@Overridepublic void before(Method method, Object[] args, @Nullable Object target) throws Throwable { //method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo);args=com.helloworld.entity.UserInfo@2e9fda69,;invokeAdviceMethod(getJoinPointMatch(), null, null); //执行增强方法"(15) 调用通知方法""执行增强方法"}}
代码块16:invokeAdviceMethod
使用给定参数调用通知方法
package org.springframework.aop.aspectj;public class AbstractAspectJAdvice implements Advice{protected Object invokeAdviceMethod(@Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex)throws Throwable {......return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex)); //执行参数绑定,然后使用参数调用通知方法"(16) 使用给定参数调用通知方法""参数:args=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo)),""执行参数绑定,然后使用参数调用通知方法"}}
代码块17:invokeAdviceMethodWithGivenArgs
方法之前
参数:args=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo)),
package org.springframework.aop.aspectj;public class AbstractAspectJAdvice implements Advice{protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable { //args=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo)),;......return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs); //TODO AopUtils.invokeJoinpointUsingReflection反射调用通知方法this.aspectInstanceFactory.getAspectInstance()获取的是切面的实例"(17) 方法之前""参数:joinPoint=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo))""TODO AopUtils.invokeJoinpointUsingReflection反射调用通知方法this.aspectInstanceFactory.getAspectInstance()获取的是切面的实例"......}}
代码块18:methodBefore
调用前置通知
参数:joinPoint=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo))
package com.helloworld.aop;public class TestAspect {@Before(value = "pointCut()")public void methodBefore(JoinPoint joinPoint) { //joinPoint=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo));String methodName = joinPoint.getSignature().getName(); //获取方法名称"(18) 调用前置通知""获取方法名称"......}}
小结:调用栈
调用methodBefore前置通知
- DemoApplication.main()
- *CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- *ReflectiveMethodInvocation.proceed()
- *ExposeInvocationInterceptor.invoke()
- *ReflectiveMethodInvocation.proceed()
- *AspectJAfterAdvice.invoke()
- *ReflectiveMethodInvocation.proceed()
- *MethodBeforeAdviceInterceptor.invoke()
- *AspectJMethodBeforeAdvice.before()
- *AbstractAspectJAdvice.invokeAdviceMethod()
- *AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
- *TestAspect.methodBefore()
调用连接点方法
将断点打到UserServiceImpl.save方法,则代码执行过程如下
代码块19:invoke
继续进行
package org.springframework.aop.framework.adapter;public class MethodBeforeAdviceInterceptor implements MethodInterceptor{@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {......this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());"(14)"return mi.proceed(); //执行目标方法"(19) 继续进行""执行目标方法"}}
代码块20:proceed
调用连接点
package org.springframework.aop.framework;public class ReflectiveMethodInvocation implements ProxyMethodInvocation{@Override@Nullablepublic Object proceed() throws Throwable {......return invokeJoinpoint(); //直接调用目标方法"(20) 调用连接点""直接调用目标方法"......}}
代码块21:invokeJoinpoint
调用
package org.springframework.aop.framework;public class CglibAopProxy implements AopProxy{@Overrideprotected Object invokeJoinpoint() throws Throwable {......return this.methodProxy.invoke(this.target, this.arguments);"(21) 调用"......}}
代码块22:invoke
保存
package org.springframework.cglib.proxy;public class MethodProxy {public Object invoke(Object obj, Object[] args) throws Throwable {......return fci.f1.invoke(fci.i1, obj, args);"(22) 保存"......}}
代码块23:save
调用连接点方法
package com.helloworld.service.impl;public class UserServiceImpl implements UserService{@Overridepublic void save(UserInfo userInfo) {System.out.println("执行保存:"+userInfo.getName());"(23) 调用连接点方法"}}
小结:调用栈
调用连接点方法
- DemoApplication.main()
- CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- ReflectiveMethodInvocation.proceed()
- ExposeInvocationInterceptor.invoke()
- ReflectiveMethodInvocation.proceed()
- AspectJAfterAdvice.invoke()
- ReflectiveMethodInvocation.proceed()
- *MethodBeforeAdviceInterceptor.invoke()
- *ReflectiveMethodInvocation.proceed()
- *CglibAopProxy$CglibMethodInvocation.invokeJoinpoint()
- *MethodProxy.invoke()
- *UserServiceImpl.save()
调用methodAfter后置通知
将断点打到TestAspect.methodAfter方法,则代码执行过程如下
代码块24:proceed
调用通知方法
package org.springframework.aop.framework;public class ReflectiveMethodInvocation implements ProxyMethodInvocation{@Override@Nullablepublic Object proceed() throws Throwable {......return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this); //It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"(24) 调用通知方法""It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"......}}
代码块25:invokeAdviceMethod
使用给定参数调用通知方法
package org.springframework.aop.aspectj;public class AbstractAspectJAdvice implements Advice{protected Object invokeAdviceMethod(@Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex)throws Throwable {......return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex)); //执行参数绑定,然后使用参数调用通知方法"(25) 使用给定参数调用通知方法""参数:args=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo)),""执行参数绑定,然后使用参数调用通知方法"}}
代码块26:invokeAdviceMethodWithGivenArgs
方法之后
参数:args=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo)),
package org.springframework.aop.aspectj;public class AbstractAspectJAdvice implements Advice{protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable { //args=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo)),;......return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs); //TODO AopUtils.invokeJoinpointUsingReflection反射调用通知方法this.aspectInstanceFactory.getAspectInstance()获取的是切面的实例"(26) 方法之后""参数:joinPoint=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo))""TODO AopUtils.invokeJoinpointUsingReflection反射调用通知方法this.aspectInstanceFactory.getAspectInstance()获取的是切面的实例"......}}
代码块27:methodAfter
调用后置通知
参数:joinPoint=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo))
package com.helloworld.aop;public class TestAspect {@After(value = "pointCut()")public void methodAfter(JoinPoint joinPoint) { //joinPoint=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo));String methodName = joinPoint.getSignature().getName(); //获取方法名称"(27) 调用后置通知""获取方法名称"......}}
小结:调用栈
调用methodAfter后置通知
- DemoApplication.main()
- CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- ReflectiveMethodInvocation.proceed()
- ExposeInvocationInterceptor.invoke()
- *ReflectiveMethodInvocation.proceed()
- *AbstractAspectJAdvice.invokeAdviceMethod()
- *AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
- *TestAspect.methodAfter()
完整代码版
下面执行userServiceImpl的save方法,首先获取userServiceImpl的通知
将断点打到MethodBeforeAdviceInterceptor.MethodBeforeAdviceInterceptor()方法,则代码执行过程如下
代码块1:main
拦截
参数:args=[]
package com.helloworld;public class DemoApplication {public static void main( String[] args ) { //args=[];AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(DemoApplication.class);UserService userService = (UserService) ctx.getBean("userServiceImpl");UserInfo userInfo = (UserInfo) ctx.getBean("user_zhangsan");userService.save(userInfo);"(1) 拦截""参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)""参数:args=com.helloworld.entity.UserInfo@2e9fda69,"}}
代码块2:intercept
获取拦截器和动态拦截通知
参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)
参数:args=com.helloworld.entity.UserInfo@2e9fda69,
package org.springframework.aop.framework;public class CglibAopProxy implements AopProxy{@Override@Nullablepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { //method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo);args=com.helloworld.entity.UserInfo@2e9fda69,;Object oldProxy = null; //被暴露在threadLocal中旧的代理对象boolean setProxyContext = false; //用来标记代理对象是否被暴露在threadLocal中 setProxyContext=false; Object target = null; //目标对象TargetSource targetSource = this.advised.getTargetSource(); //目标类 targetSource=SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]; try {if (this.advised.exposeProxy) {// Make invocation available if necessary.oldProxy = AopContext.setCurrentProxy(proxy); //将代理对象暴露出去setProxyContext = true; //将setProxyContext置为true}// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...target = targetSource.getTarget(); //目标对象可能源自一个池或者一个简单的方法Class<?> targetClass = (target != null ? target.getClass() : null); //?获取目标对象类型 targetClass=class com.helloworld.service.impl.UserServiceImpl; List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass); //Get the interception chain for this method.1-获取目标方法的拦截链 chain=org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6,org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect',org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,; "(2) 获取拦截器和动态拦截通知""参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)""参数:targetClass=class com.helloworld.service.impl.UserServiceImpl""Get the interception chain for this method.1-获取目标方法的拦截链 chain=org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6,org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect',org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,;"Object retVal;// Check whether we only have one InvokerInterceptor: that is,// no real advice, but just reflective invocation of the target.if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {// We can skip creating a MethodInvocation: just invoke the target directly.// Note that the final invoker must be an InvokerInterceptor, so we know// it does nothing but a reflective operation on the target, and no hot// swapping or fancy proxying.Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); //如果没有拦截器链,直接执行目标方法; ? ??? ??? // 拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)retVal = methodProxy.invoke(target, argsToUse); //如果拦截器为空则直接执行目标方法}else {// We need to create a method invocation...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); //必须释放来自TargetSource中的目标对象}if (setProxyContext) {// Restore old proxy.AopContext.setCurrentProxy(oldProxy); //需要将旧的代理再放回到上线文中}}}}
代码块3:getInterceptorsAndDynamicInterceptionAdvice
获取拦截器和动态拦截通知
参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)
参数:targetClass=class com.helloworld.service.impl.UserServiceImpl
package org.springframework.aop.framework;public class AdvisedSupport extends ProxyConfig implements Advised{public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) { //method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo);targetClass=class com.helloworld.service.impl.UserServiceImpl;MethodCacheKey cacheKey = new MethodCacheKey(method); //缓存对象 cacheKey=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo); List<Object> cached = this.methodCache.get(cacheKey); //这里使用了缓存来提高效率,第一次获取还是要创建的。使用了 advisorChainFactory 生成拦截器链,advisorChainFactory 是 DefaultAdvisorChainFactory 的实例if (cached == null) { //如果没有缓存则从缓存里面拿cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice( // cached=org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6,org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect',org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,; this, method, targetClass);"(3) 获取拦截器和动态拦截通知""参数:config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false""参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)""参数:targetClass=class com.helloworld.service.impl.UserServiceImpl""cached=org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6,org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect',org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,;"this, method, targetClass);this.methodCache.put(cacheKey, cached); //为目的对象的目标方法的拦截器链建立 cached=org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6,org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect',org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,; cacheKey=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo); }return cached; // org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6,org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect',org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,; }}
代码块4:getInterceptorsAndDynamicInterceptionAdvice
获取拦截器
参数:config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor…
参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)
参数:targetClass=class com.helloworld.service.impl.UserServiceImpl
package org.springframework.aop.framework;public class DefaultAdvisorChainFactory implements AdvisorChainFactory{@Overridepublic List<Object> getInterceptorsAndDynamicInterceptionAdvice( //config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false;method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo);targetClass=class com.helloworld.service.impl.UserServiceImpl;Advised config, Method method, @Nullable Class<?> targetClass) {// This is somewhat tricky... We have to process introductions first,// but we need to preserve order in the ultimate list.AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance(); //* 调用DefaultAdvisorAdapterRegistry构造方法获取通知适配器注册器,包括:* 1. MethodBeforeAdviceAdapter* 2. AfterReturningAdviceAdapter* 3. ThrowsAdviceAdapter** Adapter添加进List中的顺序就是上面的顺序。** GlobalAdvisorAdapterRegistry.getInstance()实际上就是去获取DefaultAdvisorAdapterRegistry中的AdapterAdvisor[] advisors = config.getAdvisors(); //config在这里就是前面所说的ProxyFactory。从ProxyFactory中获取通知 advisors=org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON,; List<Object> interceptorList = new ArrayList<>(advisors.length); //要返回的结果对象Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass()); //获取被调用方法所在类实际的类型 actualClass=class com.helloworld.service.impl.UserServiceImpl; Boolean hasIntroductions = null;for (Advisor advisor : advisors) { // advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; if (advisor instanceof PointcutAdvisor) {// Add it conditionally.PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor; //将通知强转为切面 pointcutAdvisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; pointcutAdvisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON; if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) { // actualClass=class com.helloworld.service.impl.UserServiceImpl; config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; actualClass=class com.helloworld.service.impl.UserServiceImpl; config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; actualClass=class com.helloworld.service.impl.UserServiceImpl; config=org.springframework.aop.framework.ProxyFactory: 0 interfaces []; 3 advisors [org.springframework.aop.interceptor.ExposeInvocationInterceptor.ADVISOR, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON, InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON]; targetSource [SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]]; proxyTargetClass=true; optimize=false; opaque=false; exposeProxy=false; frozen=false; MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher(); //获取 MethodMatcher ,用来匹配目标方法,如果匹配就放入到拦截器链中。pointcut 就是在这里使用的 mm=MethodMatcher.TRUE; mm=AspectJExpressionPointcut: () pointCut(); mm=AspectJExpressionPointcut: () pointCut(); boolean match;if (mm instanceof IntroductionAwareMethodMatcher) {if (hasIntroductions == null) {hasIntroductions = hasMatchingIntroductions(advisors, actualClass); // hasIntroductions=false; }match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions); //根据目标类型和方法,与方法匹配器是否匹配 match=true; match=true; }else {match = mm.matches(method, actualClass); //方法是否匹配 match=true; }if (match) {MethodInterceptor[] interceptors = registry.getInterceptors(advisor); //将advisor转为MethodInterceptor interceptors=org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6,; interceptors=org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect',; interceptors=org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,; "(4) 获取拦截器""参数:advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON""将advisor转为MethodInterceptor interceptors=org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6,; interceptors=org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect',; interceptors=org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,;"if (mm.isRuntime()) {// Creating a new object instance in the getInterceptors() method// isn't a problem as we normally cache created chains.for (MethodInterceptor interceptor : interceptors) {interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm)); //封装为 InterceptorAndDynamicMethodMatcher}}else {interceptorList.addAll(Arrays.asList(interceptors)); //不是动态的MethodMatcher,将所有的拦截器加入到返回List}}}}else if (advisor instanceof IntroductionAdvisor) {IntroductionAdvisor ia = (IntroductionAdvisor) advisor;if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {Interceptor[] interceptors = registry.getInterceptors(advisor); //其他类型interceptorList.addAll(Arrays.asList(interceptors)); //不是动态的MethodMatcher,将所有的拦截器加入到返回List}}else {Interceptor[] interceptors = registry.getInterceptors(advisor); //其他类型interceptorList.addAll(Arrays.asList(interceptors)); //不是动态的MethodMatcher,将所有的拦截器加入到返回List}}return interceptorList; //* 这里返回的拦截器链为:* 1.ExposeInvocationInterceptor* 2.AspectJAfterAdvice* 3.AspectJAroundAdvice* 4.MethodBeforeAdviceInterceptor org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6,org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect',org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,; }}
代码块5:getInterceptors
获取拦截器
参数:advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.T…
package org.springframework.aop.framework.adapter;public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry{@Overridepublic MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException { //advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON;List<MethodInterceptor> interceptors = new ArrayList<>(3);Advice advice = advisor.getAdvice(); //获取通知 advice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect'; if (advice instanceof MethodInterceptor) {interceptors.add((MethodInterceptor) advice); //如果是MethodInterceptor 直接加入到MethodInterceptor list 中不需要适配}for (AdvisorAdapter adapter : this.adapters) {if (adapter.supportsAdvice(advice)) { // advice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect'; interceptors.add(adapter.getInterceptor(advisor)); //获取方法拦截器并放入到集合中返回"(5) 获取拦截器""参数:advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON""获取方法拦截器并放入到集合中返回"}}if (interceptors.isEmpty()) {throw new UnknownAdviceTypeException(advisor.getAdvice());}return interceptors.toArray(new MethodInterceptor[0]); //3.返回结果 org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor@53dacd14,; }}
代码块6:getInterceptor
init
参数:advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.T…
package org.springframework.aop.framework.adapter;public class MethodBeforeAdviceAdapter implements AdvisorAdapter{@Overridepublic MethodInterceptor getInterceptor(Advisor advisor) { //advisor=InstantiationModelAwarePointcutAdvisor: expression [pointCut()]; advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; perClauseKind=SINGLETON;MethodBeforeAdvice advice = (MethodBeforeAdvice) advisor.getAdvice(); //获取advice,创建 MethodBeforeAdviceInterceptor 对象并返回 advice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect'; return new MethodBeforeAdviceInterceptor(advice); //通知类型匹配对应的拦截器"(6) init""参数:advice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect'""通知类型匹配对应的拦截器"}}
代码块7:MethodBeforeAdviceInterceptor()
创建前置通知拦截器对象
参数:advice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspe…
package org.springframework.aop.framework.adapter;public class MethodBeforeAdviceInterceptor implements MethodInterceptor{public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) { //advice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect';Assert.notNull(advice, "Advice must not be null"); // advice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect'; this.advice = advice; // this.advice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect'; "(7) 创建前置通知拦截器对象""this.advice=org.springframework.aop.aspectj.AspectJMethodBeforeAdvice: advice method [public void com.helloworld.aop.TestAspect.methodBefore(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect';"}}
小结:调用栈
下面执行userServiceImpl的save方法,首先获取userServiceImpl的通知
- *DemoApplication.main()
- *CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- *AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice()
- *DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()
- *DefaultAdvisorAdapterRegistry.getInterceptors()
- *MethodBeforeAdviceAdapter.getInterceptor()
- *MethodBeforeAdviceInterceptor.MethodBeforeAdviceInterceptor()
调用methodBefore前置通知
将断点打到TestAspect.methodBefore方法,则代码执行过程如下
代码块8:intercept
继续进行
参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)
参数:args=com.helloworld.entity.UserInfo@2e9fda69,
package org.springframework.aop.framework;public class CglibAopProxy implements AopProxy{@Override@Nullablepublic Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable { //method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo);args=com.helloworld.entity.UserInfo@2e9fda69,;Object oldProxy = null; //被暴露在threadLocal中旧的代理对象boolean setProxyContext = false; //用来标记代理对象是否被暴露在threadLocal中 setProxyContext=false; Object target = null; //目标对象TargetSource targetSource = this.advised.getTargetSource(); //目标类 targetSource=SingletonTargetSource for target object [com.helloworld.service.impl.UserServiceImpl@23aa363a]; try {if (this.advised.exposeProxy) {// Make invocation available if necessary.oldProxy = AopContext.setCurrentProxy(proxy); //将代理对象暴露出去setProxyContext = true; //将setProxyContext置为true}// Get as late as possible to minimize the time we "own" the target, in case it comes from a pool...target = targetSource.getTarget(); //目标对象可能源自一个池或者一个简单的方法Class<?> targetClass = (target != null ? target.getClass() : null); //?获取目标对象类型 targetClass=class com.helloworld.service.impl.UserServiceImpl; List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);"(2)"Object retVal;// Check whether we only have one InvokerInterceptor: that is,// no real advice, but just reflective invocation of the target.if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {// We can skip creating a MethodInvocation: just invoke the target directly.// Note that the final invoker must be an InvokerInterceptor, so we know// it does nothing but a reflective operation on the target, and no hot// swapping or fancy proxying.Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args); //如果没有拦截器链,直接执行目标方法; ? ??? ??? // 拦截器链(每一个通知方法又被包装为方法拦截器,利用MethodInterceptor机制)retVal = methodProxy.invoke(target, argsToUse); //如果拦截器为空则直接执行目标方法}else {// We need to create a method invocation...retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed(); //封装拦截器链并执行"(8) 继续进行""封装拦截器链并执行"}retVal = processReturnType(proxy, target, method, retVal); //处理返回值类型return retVal;}finally {if (target != null && !targetSource.isStatic()) {targetSource.releaseTarget(target); //必须释放来自TargetSource中的目标对象}if (setProxyContext) {// Restore old proxy.AopContext.setCurrentProxy(oldProxy); //需要将旧的代理再放回到上线文中}}}}
代码块9:proceed
调用
package org.springframework.aop.framework;public class ReflectiveMethodInvocation implements ProxyMethodInvocation{@Override@Nullablepublic Object proceed() throws Throwable {// We start with an index of -1 and increment early.if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint(); //直接调用目标方法}Object interceptorOrInterceptionAdvice = // interceptorOrInterceptionAdvice=org.springframework.aop.interceptor.ExposeInvocationInterceptor@241e8ea6; 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)) {return dm.interceptor.invoke(this); //比如 @After @Before 对应的增强器(拦截器)的方法比如 @After 对应的增强器 AspectJAfterAdvice 的invoke方法为:MethodInvocation.proceed();}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); //It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"(9) 调用""It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"}}}
代码块10:invoke
继续进行
package org.springframework.aop.interceptor;public class ExposeInvocationInterceptor implements MethodInterceptor{@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {MethodInvocation oldInvocation = invocation.get();invocation.set(mi); //将 mi 设置到 ThreadLocal 中try {return mi.proceed(); //执行目标方法"(10) 继续进行""执行目标方法"}finally {invocation.set(oldInvocation);}}}
代码块11:proceed
调用
package org.springframework.aop.framework;public class ReflectiveMethodInvocation implements ProxyMethodInvocation{@Override@Nullablepublic Object proceed() throws Throwable {// We start with an index of -1 and increment early.if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint(); //直接调用目标方法}Object interceptorOrInterceptionAdvice = // interceptorOrInterceptionAdvice=org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect'; 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)) {return dm.interceptor.invoke(this); //比如 @After @Before 对应的增强器(拦截器)的方法比如 @After 对应的增强器 AspectJAfterAdvice 的invoke方法为:MethodInvocation.proceed();}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); //It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"(11) 调用""It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"}}}
代码块12:invoke
继续进行
package org.springframework.aop.aspectj;public class AspectJAfterAdvice extends AbstractAspectJAdvice implements MethodInterceptor{@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {try {return mi.proceed(); //执行目标方法"(12) 继续进行""执行目标方法"}finally {invokeAdviceMethod(getJoinPointMatch(), null, null); //执行增强方法}}}
代码块13:proceed
调用
package org.springframework.aop.framework;public class ReflectiveMethodInvocation implements ProxyMethodInvocation{@Override@Nullablepublic Object proceed() throws Throwable {// We start with an index of -1 and increment early.if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint(); //直接调用目标方法}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)) {return dm.interceptor.invoke(this); //比如 @After @Before 对应的增强器(拦截器)的方法比如 @After 对应的增强器 AspectJAfterAdvice 的invoke方法为:MethodInvocation.proceed();}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); //It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"(13) 调用""It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"}}}
代码块14:invoke
在此之前
package org.springframework.aop.framework.adapter;public class MethodBeforeAdviceInterceptor implements MethodInterceptor{@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); //执行拦截器before方法"(14) 在此之前""参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)""参数:args=com.helloworld.entity.UserInfo@2e9fda69,""执行拦截器before方法"return mi.proceed(); //执行目标方法}}
代码块15:before
调用通知方法
参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)
参数:args=com.helloworld.entity.UserInfo@2e9fda69,
package org.springframework.aop.aspectj;public class AspectJMethodBeforeAdvice extends AbstractAspectJAdvice implements MethodBeforeAdvice{@Overridepublic void before(Method method, Object[] args, @Nullable Object target) throws Throwable { //method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo);args=com.helloworld.entity.UserInfo@2e9fda69,;invokeAdviceMethod(getJoinPointMatch(), null, null); //执行增强方法"(15) 调用通知方法""执行增强方法"}}
代码块16:invokeAdviceMethod
使用给定参数调用通知方法
package org.springframework.aop.aspectj;public class AbstractAspectJAdvice implements Advice{protected Object invokeAdviceMethod(@Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex)throws Throwable {return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex)); //执行参数绑定,然后使用参数调用通知方法"(16) 使用给定参数调用通知方法""参数:args=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo)),""执行参数绑定,然后使用参数调用通知方法"}}
代码块17:invokeAdviceMethodWithGivenArgs
方法之前
参数:args=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo)),
package org.springframework.aop.aspectj;public class AbstractAspectJAdvice implements Advice{protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable { //args=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo)),;Object[] actualArgs = args; //第一步: 获取参数 actualArgs=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo)),; if (this.aspectJAdviceMethod.getParameterCount() == 0) {actualArgs = null;}try {ReflectionUtils.makeAccessible(this.aspectJAdviceMethod); //使用反射,激活增强处理方法// TODO AopUtils.invokeJoinpointUsingReflectionreturn this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs); //TODO AopUtils.invokeJoinpointUsingReflection反射调用通知方法this.aspectInstanceFactory.getAspectInstance()获取的是切面的实例"(17) 方法之前""参数:joinPoint=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo))""TODO AopUtils.invokeJoinpointUsingReflection反射调用通知方法this.aspectInstanceFactory.getAspectInstance()获取的是切面的实例"}catch (IllegalArgumentException ex) {throw new AopInvocationException("Mismatch on arguments to advice method [" +this.aspectJAdviceMethod + "]; pointcut expression [" +this.pointcut.getPointcutExpression() + "]", ex);}catch (InvocationTargetException ex) {throw ex.getTargetException();}}}
代码块18:methodBefore
调用前置通知
参数:joinPoint=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo))
package com.helloworld.aop;public class TestAspect {@Before(value = "pointCut()")public void methodBefore(JoinPoint joinPoint) { //joinPoint=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo));String methodName = joinPoint.getSignature().getName(); //获取方法名称"(18) 调用前置通知""获取方法名称"System.out.println("执行目标方法【"+methodName+"】的<前置通知>,入参"+ Arrays.asList(joinPoint.getArgs()));}}
小结:调用栈
调用methodBefore前置通知
- DemoApplication.main()
- *CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- *ReflectiveMethodInvocation.proceed()
- *ExposeInvocationInterceptor.invoke()
- *ReflectiveMethodInvocation.proceed()
- *AspectJAfterAdvice.invoke()
- *ReflectiveMethodInvocation.proceed()
- *MethodBeforeAdviceInterceptor.invoke()
- *AspectJMethodBeforeAdvice.before()
- *AbstractAspectJAdvice.invokeAdviceMethod()
- *AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
- *TestAspect.methodBefore()
调用连接点方法
将断点打到UserServiceImpl.save方法,则代码执行过程如下
代码块19:invoke
继续进行
package org.springframework.aop.framework.adapter;public class MethodBeforeAdviceInterceptor implements MethodInterceptor{@Overridepublic Object invoke(MethodInvocation mi) throws Throwable {this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());"(14)"return mi.proceed(); //执行目标方法"(19) 继续进行""执行目标方法"}}
代码块20:proceed
调用连接点
package org.springframework.aop.framework;public class ReflectiveMethodInvocation implements ProxyMethodInvocation{@Override@Nullablepublic Object proceed() throws Throwable {// We start with an index of -1 and increment early.if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint(); //直接调用目标方法"(20) 调用连接点""直接调用目标方法"}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)) {return dm.interceptor.invoke(this); //比如 @After @Before 对应的增强器(拦截器)的方法比如 @After 对应的增强器 AspectJAfterAdvice 的invoke方法为:MethodInvocation.proceed();}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); //It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可}}}
代码块21:invokeJoinpoint
调用
package org.springframework.aop.framework;public class CglibAopProxy implements AopProxy{@Overrideprotected Object invokeJoinpoint() throws Throwable {if (this.methodProxy != null) {return this.methodProxy.invoke(this.target, this.arguments);"(21) 调用"}else {return super.invokeJoinpoint();}}}
代码块22:invoke
保存
package org.springframework.cglib.proxy;public class MethodProxy {public Object invoke(Object obj, Object[] args) throws Throwable {try {init();FastClassInfo fci = fastClassInfo;return fci.f1.invoke(fci.i1, obj, args);"(22) 保存"}catch (InvocationTargetException ex) {throw ex.getTargetException();}catch (IllegalArgumentException ex) {if (fastClassInfo.i1 < 0) {throw new IllegalArgumentException("Protected method: " + sig1);}throw ex;}}}
代码块23:save
调用连接点方法
package com.helloworld.service.impl;public class UserServiceImpl implements UserService{@Overridepublic void save(UserInfo userInfo) {System.out.println("执行保存:"+userInfo.getName());"(23) 调用连接点方法"}}
小结:调用栈
调用连接点方法
- DemoApplication.main()
- CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- ReflectiveMethodInvocation.proceed()
- ExposeInvocationInterceptor.invoke()
- ReflectiveMethodInvocation.proceed()
- AspectJAfterAdvice.invoke()
- ReflectiveMethodInvocation.proceed()
- *MethodBeforeAdviceInterceptor.invoke()
- *ReflectiveMethodInvocation.proceed()
- *CglibAopProxy$CglibMethodInvocation.invokeJoinpoint()
- *MethodProxy.invoke()
- *UserServiceImpl.save()
调用methodAfter后置通知
将断点打到TestAspect.methodAfter方法,则代码执行过程如下
代码块24:proceed
调用通知方法
package org.springframework.aop.framework;public class ReflectiveMethodInvocation implements ProxyMethodInvocation{@Override@Nullablepublic Object proceed() throws Throwable {// We start with an index of -1 and increment early.if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return invokeJoinpoint(); //直接调用目标方法}Object interceptorOrInterceptionAdvice = // interceptorOrInterceptionAdvice=org.springframework.aop.aspectj.AspectJAfterAdvice: advice method [public void com.helloworld.aop.TestAspect.methodAfter(org.aspectj.lang.JoinPoint)]; aspect name 'testAspect'; 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)) {return dm.interceptor.invoke(this); //比如 @After @Before 对应的增强器(拦截器)的方法比如 @After 对应的增强器 AspectJAfterAdvice 的invoke方法为:MethodInvocation.proceed();}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); //It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"(24) 调用通知方法""It's an interceptor, so we just invoke it: The pointcut will havebeen evaluated statically before this object was constructed.普通的拦截器,直接调用即可"}}}
代码块25:invokeAdviceMethod
使用给定参数调用通知方法
package org.springframework.aop.aspectj;public class AbstractAspectJAdvice implements Advice{protected Object invokeAdviceMethod(@Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable ex)throws Throwable {return invokeAdviceMethodWithGivenArgs(argBinding(getJoinPoint(), jpMatch, returnValue, ex)); //执行参数绑定,然后使用参数调用通知方法"(25) 使用给定参数调用通知方法""参数:args=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo)),""执行参数绑定,然后使用参数调用通知方法"}}
代码块26:invokeAdviceMethodWithGivenArgs
方法之后
参数:args=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo)),
package org.springframework.aop.aspectj;public class AbstractAspectJAdvice implements Advice{protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable { //args=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo)),;Object[] actualArgs = args; //第一步: 获取参数 actualArgs=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo)),; if (this.aspectJAdviceMethod.getParameterCount() == 0) {actualArgs = null;}try {ReflectionUtils.makeAccessible(this.aspectJAdviceMethod); //使用反射,激活增强处理方法// TODO AopUtils.invokeJoinpointUsingReflectionreturn this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs); //TODO AopUtils.invokeJoinpointUsingReflection反射调用通知方法this.aspectInstanceFactory.getAspectInstance()获取的是切面的实例"(26) 方法之后""参数:joinPoint=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo))""TODO AopUtils.invokeJoinpointUsingReflection反射调用通知方法this.aspectInstanceFactory.getAspectInstance()获取的是切面的实例"}catch (IllegalArgumentException ex) {throw new AopInvocationException("Mismatch on arguments to advice method [" +this.aspectJAdviceMethod + "]; pointcut expression [" +this.pointcut.getPointcutExpression() + "]", ex);}catch (InvocationTargetException ex) {throw ex.getTargetException();}}}
代码块27:methodAfter
调用后置通知
参数:joinPoint=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo))
package com.helloworld.aop;public class TestAspect {@After(value = "pointCut()")public void methodAfter(JoinPoint joinPoint) { //joinPoint=execution(void com.helloworld.service.impl.UserServiceImpl.save(UserInfo));String methodName = joinPoint.getSignature().getName(); //获取方法名称"(27) 调用后置通知""获取方法名称"System.out.println("执行目标方法【"+methodName+"】的<后置通知>,入参"+Arrays.asList(joinPoint.getArgs()));}}
小结:调用栈
调用methodAfter后置通知
- DemoApplication.main()
- CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- ReflectiveMethodInvocation.proceed()
- ExposeInvocationInterceptor.invoke()
- *ReflectiveMethodInvocation.proceed()
- *AbstractAspectJAdvice.invokeAdviceMethod()
- *AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
- *TestAspect.methodAfter()
在线记录源码调试之@EnableAspectJAutoProxy与Spring AOP(三)调用被代理方法userServiceImpl.save(user)相关推荐
- 在线记录源码调试之@Qualifier源码分析
测试用例1 在DemoApplication中注册两个bean,用户zhangsan和用户lisi,给demoApplication对象注入zhangsan,并标注@Qualifier @Config ...
- Spring AOP源码分析(四)Spring AOP的JDK动态代理
2019独角兽企业重金招聘Python工程师标准>>> 本篇文章将会介绍上一个例子中的源码执行情况,从中熟悉整个SpringAOP的一些概念和接口设计. 首先整个SpringAOP的 ...
- Spring AOP源码分析(六)Spring AOP配置的背后
本篇文章主要对Spring AOP配置背后进行了哪些事情做下说明.还是如上类似的工程,在xml中AOP拦截配置如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 < ...
- webuploader 怎么在react中_另辟蹊径搭建阅读React源码调试环境支持所有React版本细分文件断点调试...
引言(为什么写这篇文章) 若要高效阅读和理解React源码,搭建调试环境是必不可少的一步.而常规方法:使用react.development.js和react-dom.development.js调试 ...
- java在线影院系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署
java在线影院系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署 java在线影院系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署 项目架构:B/S架构 开发语言:Ja ...
- java计算机毕业设计在线问答平台MyBatis+系统+LW文档+源码+调试部署
java计算机毕业设计在线问答平台MyBatis+系统+LW文档+源码+调试部署 java计算机毕业设计在线问答平台MyBatis+系统+LW文档+源码+调试部署 本源码技术栈: 项目架构:B/S架构 ...
- 计算机毕业设计JAVA软考在线题库系统mybatis+源码+调试部署+系统+数据库+lw
计算机毕业设计JAVA软考在线题库系统mybatis+源码+调试部署+系统+数据库+lw 本源码技术栈: 项目架构:B/S架构 开发语言:Java语言 开发软件:idea eclipse 前端技术:L ...
- java计算机毕业设计高铁在线购票系统MyBatis+系统+LW文档+源码+调试部署
java计算机毕业设计高铁在线购票系统MyBatis+系统+LW文档+源码+调试部署 java计算机毕业设计高铁在线购票系统MyBatis+系统+LW文档+源码+调试部署 本源码技术栈: 项目架构:B ...
- java计算机毕业设计计算机课程在线培训学习管理系统MyBatis+系统+LW文档+源码+调试部署
java计算机毕业设计计算机课程在线培训学习管理系统MyBatis+系统+LW文档+源码+调试部署 java计算机毕业设计计算机课程在线培训学习管理系统MyBatis+系统+LW文档+源码+调试部署 ...
最新文章
- 01矩阵等比放大(Java代码、ACM格式)--2021.9.7百度笔试研发A卷
- 机器学习中的矩阵向量求导(二) 矩阵向量求导之定义法
- 暗时间(一)设计你自己的进度条
- java rmi 超时_java RMI服务超时
- 也分享自己做的JS扫雷小游戏
- 前端学习(1749):前端调试值之如何查看整站的资源和编辑
- android的app语言无法切换,Android应用实现多语言切换
- 【火炉炼AI】机器学习006-用决策树回归器构建房价评估模型
- 那些兼职中你不知道的事
- SQLserver查询练习
- vmware linux ssh密码,从 CLI 重置 Linux VM 密码和 SSH 密钥 - Azure Virtual Machines | Microsoft Docs...
- chrome-推荐13个插件
- Robomaster视觉教程(二)Win10+VS201x+Opencv3.4.x环境搭建
- java实现列表拖动排序
- edittext 内容长度
- 质因数分解-P1069 [NOIP2009 普及组] 细胞分裂
- Python 多重共线性检验
- 使用pandas的merge出现Empty DataFrame 和 Index: []
- 使用Qt Designer制作软件的图形界面
- 浅谈Linux标准的文件系统(Ext2/Ext3/Ext4)
热门文章
- 过滤器,监听器,拦截器的区别
- Visual Studio C++ 中小微企业信息管理系统设计与实现之开发财务管理系统
- PLC控制技术与组态技术实训装置
- c语言围棋原理,围棋中的数学原理
- 下载centos7.6光盘映像文件,使用VMware12创建虚拟机,设置固定IP,最全图文教程
- Usb 声卡 linux,树莓派:使用usb声卡播放音乐
- Cu50温度传感器的误差分析
- pytorch3d学习之pytorch3d.ops
- AI周报丨标清变4k?B站超分辨率算法开源;强化学习算法控制核聚变登上《nature》
- D类音频功放输出功率测试