测试用例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的通知

  1. *DemoApplication.main()
  2. *CglibAopProxy$DynamicAdvisedInterceptor.intercept()
  3. *AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice()
  4. *DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()
  5. *DefaultAdvisorAdapterRegistry.getInterceptors()
  6. *MethodBeforeAdviceAdapter.getInterceptor()
  7. *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前置通知

  1. DemoApplication.main()
  2. *CglibAopProxy$DynamicAdvisedInterceptor.intercept()
  3. *ReflectiveMethodInvocation.proceed()
  4. *ExposeInvocationInterceptor.invoke()
  5. *ReflectiveMethodInvocation.proceed()
  6. *AspectJAfterAdvice.invoke()
  7. *ReflectiveMethodInvocation.proceed()
  8. *MethodBeforeAdviceInterceptor.invoke()
  9. *AspectJMethodBeforeAdvice.before()
  10. *AbstractAspectJAdvice.invokeAdviceMethod()
  11. *AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
  12. *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) 调用连接点方法"}}

小结:调用栈

调用连接点方法

  1. DemoApplication.main()
  2. CglibAopProxy$DynamicAdvisedInterceptor.intercept()
  3. ReflectiveMethodInvocation.proceed()
  4. ExposeInvocationInterceptor.invoke()
  5. ReflectiveMethodInvocation.proceed()
  6. AspectJAfterAdvice.invoke()
  7. ReflectiveMethodInvocation.proceed()
  8. *MethodBeforeAdviceInterceptor.invoke()
  9. *ReflectiveMethodInvocation.proceed()
  10. *CglibAopProxy$CglibMethodInvocation.invokeJoinpoint()
  11. *MethodProxy.invoke()
  12. *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后置通知

  1. DemoApplication.main()
  2. CglibAopProxy$DynamicAdvisedInterceptor.intercept()
  3. ReflectiveMethodInvocation.proceed()
  4. ExposeInvocationInterceptor.invoke()
  5. *ReflectiveMethodInvocation.proceed()
  6. *AbstractAspectJAdvice.invokeAdviceMethod()
  7. *AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
  8. *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的通知

  1. *DemoApplication.main()
  2. *CglibAopProxy$DynamicAdvisedInterceptor.intercept()
  3. *AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice()
  4. *DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()
  5. *DefaultAdvisorAdapterRegistry.getInterceptors()
  6. *MethodBeforeAdviceAdapter.getInterceptor()
  7. *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前置通知

  1. DemoApplication.main()
  2. *CglibAopProxy$DynamicAdvisedInterceptor.intercept()
  3. *ReflectiveMethodInvocation.proceed()
  4. *ExposeInvocationInterceptor.invoke()
  5. *ReflectiveMethodInvocation.proceed()
  6. *AspectJAfterAdvice.invoke()
  7. *ReflectiveMethodInvocation.proceed()
  8. *MethodBeforeAdviceInterceptor.invoke()
  9. *AspectJMethodBeforeAdvice.before()
  10. *AbstractAspectJAdvice.invokeAdviceMethod()
  11. *AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
  12. *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) 调用连接点方法"}}

小结:调用栈

调用连接点方法

  1. DemoApplication.main()
  2. CglibAopProxy$DynamicAdvisedInterceptor.intercept()
  3. ReflectiveMethodInvocation.proceed()
  4. ExposeInvocationInterceptor.invoke()
  5. ReflectiveMethodInvocation.proceed()
  6. AspectJAfterAdvice.invoke()
  7. ReflectiveMethodInvocation.proceed()
  8. *MethodBeforeAdviceInterceptor.invoke()
  9. *ReflectiveMethodInvocation.proceed()
  10. *CglibAopProxy$CglibMethodInvocation.invokeJoinpoint()
  11. *MethodProxy.invoke()
  12. *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后置通知

  1. DemoApplication.main()
  2. CglibAopProxy$DynamicAdvisedInterceptor.intercept()
  3. ReflectiveMethodInvocation.proceed()
  4. ExposeInvocationInterceptor.invoke()
  5. *ReflectiveMethodInvocation.proceed()
  6. *AbstractAspectJAdvice.invokeAdviceMethod()
  7. *AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
  8. *TestAspect.methodAfter()

在线记录源码调试之@EnableAspectJAutoProxy与Spring AOP(三)调用被代理方法userServiceImpl.save(user)相关推荐

  1. 在线记录源码调试之@Qualifier源码分析

    测试用例1 在DemoApplication中注册两个bean,用户zhangsan和用户lisi,给demoApplication对象注入zhangsan,并标注@Qualifier @Config ...

  2. Spring AOP源码分析(四)Spring AOP的JDK动态代理

    2019独角兽企业重金招聘Python工程师标准>>> 本篇文章将会介绍上一个例子中的源码执行情况,从中熟悉整个SpringAOP的一些概念和接口设计. 首先整个SpringAOP的 ...

  3. Spring AOP源码分析(六)Spring AOP配置的背后

    本篇文章主要对Spring AOP配置背后进行了哪些事情做下说明.还是如上类似的工程,在xml中AOP拦截配置如下: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 < ...

  4. webuploader 怎么在react中_另辟蹊径搭建阅读React源码调试环境支持所有React版本细分文件断点调试...

    引言(为什么写这篇文章) 若要高效阅读和理解React源码,搭建调试环境是必不可少的一步.而常规方法:使用react.development.js和react-dom.development.js调试 ...

  5. java在线影院系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署

    java在线影院系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署 java在线影院系统计算机毕业设计MyBatis+系统+LW文档+源码+调试部署 项目架构:B/S架构 开发语言:Ja ...

  6. java计算机毕业设计在线问答平台MyBatis+系统+LW文档+源码+调试部署

    java计算机毕业设计在线问答平台MyBatis+系统+LW文档+源码+调试部署 java计算机毕业设计在线问答平台MyBatis+系统+LW文档+源码+调试部署 本源码技术栈: 项目架构:B/S架构 ...

  7. 计算机毕业设计JAVA软考在线题库系统mybatis+源码+调试部署+系统+数据库+lw

    计算机毕业设计JAVA软考在线题库系统mybatis+源码+调试部署+系统+数据库+lw 本源码技术栈: 项目架构:B/S架构 开发语言:Java语言 开发软件:idea eclipse 前端技术:L ...

  8. java计算机毕业设计高铁在线购票系统MyBatis+系统+LW文档+源码+调试部署

    java计算机毕业设计高铁在线购票系统MyBatis+系统+LW文档+源码+调试部署 java计算机毕业设计高铁在线购票系统MyBatis+系统+LW文档+源码+调试部署 本源码技术栈: 项目架构:B ...

  9. java计算机毕业设计计算机课程在线培训学习管理系统MyBatis+系统+LW文档+源码+调试部署

    java计算机毕业设计计算机课程在线培训学习管理系统MyBatis+系统+LW文档+源码+调试部署 java计算机毕业设计计算机课程在线培训学习管理系统MyBatis+系统+LW文档+源码+调试部署 ...

最新文章

  1. 01矩阵等比放大(Java代码、ACM格式)--2021.9.7百度笔试研发A卷
  2. 机器学习中的矩阵向量求导(二) 矩阵向量求导之定义法
  3. 暗时间(一)设计你自己的进度条
  4. java rmi 超时_java RMI服务超时
  5. 也分享自己做的JS扫雷小游戏
  6. 前端学习(1749):前端调试值之如何查看整站的资源和编辑
  7. android的app语言无法切换,Android应用实现多语言切换
  8. 【火炉炼AI】机器学习006-用决策树回归器构建房价评估模型
  9. 那些兼职中你不知道的事
  10. SQLserver查询练习
  11. vmware linux ssh密码,从 CLI 重置 Linux VM 密码和 SSH 密钥 - Azure Virtual Machines | Microsoft Docs...
  12. chrome-推荐13个插件
  13. Robomaster视觉教程(二)Win10+VS201x+Opencv3.4.x环境搭建
  14. java实现列表拖动排序
  15. edittext 内容长度
  16. 质因数分解-P1069 [NOIP2009 普及组] 细胞分裂
  17. Python 多重共线性检验
  18. 使用pandas的merge出现Empty DataFrame 和 Index: []
  19. 使用Qt Designer制作软件的图形界面
  20. 浅谈Linux标准的文件系统(Ext2/Ext3/Ext4)

热门文章

  1. 过滤器,监听器,拦截器的区别
  2. Visual Studio C++ 中小微企业信息管理系统设计与实现之开发财务管理系统
  3. PLC控制技术与组态技术实训装置
  4. c语言围棋原理,围棋中的数学原理
  5. 下载centos7.6光盘映像文件,使用VMware12创建虚拟机,设置固定IP,最全图文教程
  6. Usb 声卡 linux,树莓派:使用usb声卡播放音乐
  7. Cu50温度传感器的误差分析
  8. pytorch3d学习之pytorch3d.ops
  9. AI周报丨标清变4k?B站超分辨率算法开源;强化学习算法控制核聚变登上《nature》
  10. D类音频功放输出功率测试