锐单电子商城 , 一站式电子元器件采购平台!
  • 电话:400-990-0325

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

时间:2023-01-20 19:00:00 fci连接器10075025

测试用例1

连接点

@Component public class UserServiceImpl implements UserService { 
              @Override     public 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
		@Nullable
		public 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{ 
        

	@Override
	public 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{ 
        

	@Override
	public 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{ 
        

	@Override
	public 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
		@Nullable
		public 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
	@Nullable
	public 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{ 
        

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable { 
        
				......

			return mi.proceed(); //执行目标方法

			"(10) 继续进行"

			"执行目标方法"

				......
	}

}

代码块11:proceed

调用

package org.springframework.aop.framework;

public class ReflectiveMethodInvocation implements ProxyMethodInvocation{ 
        

	@Override
	@Nullable
	public 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{ 
        

	@Override
	public Object invoke(MethodInvocation mi) throws Throwable { 
        
				......

			return mi.proceed(); //执行目标方法

			"(12) 继续进行"

			"执行目标方法"

				......
	}

}

代码块13:proceed

调用

package org.springframework.aop.framework;

public class ReflectiveMethodInvocation implements ProxyMethodInvocation{ 
        

	@Override
	@Nullable
	public 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{ 
        

	@Override
	public 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{ 
        

	@Override
	public 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{ 
        

	@Override
	public 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
	@Nullable
	public Object proceed() throws Throwable { 
        
				......

			return invokeJoinpoint(); //直接调用目标方法

			"(20) 调用连接点"

			"直接调用目标方法"

				......
	}

}

代码块21:invokeJoinpoint

调用

package org.springframework.aop.framework;

public class CglibAopProxy implements AopProxy{ 
        

		@Override
		protected 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{ 
        

    @Override
    public 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
	@Nullable
	public 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
		@Nullable
		public 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{ 
        

	@Override
	public 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中的Adapter
		Advisor[] 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{ 
        

	@Override
	public 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{ 
        

	@Override
	public 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
		@Nullable
		public 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
	@Nullable
	public 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{ 
        

	@Override
	public 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
	@Nullable
	public 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{ 
        

	@Override
	public 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
	@Nullable
	public 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{ 
        

	@Override
	public 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{ 
        

	@Override
	public 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.invokeJoinpointUsingReflection

			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()获取的是切面的实例"

		}
		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{ 
        

	@Override
	public 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
	@Nullable
	public 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{ 
        

		@Override
		protected 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{ 
        

    @Override
    public 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
	@Nullable
	public 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.invokeJoinpointUsingReflection

			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()获取的是切面的实例"

		}
		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()
锐单商城拥有海量元器件数据手册IC替代型号,打造电子元器件IC百科大全!

相关文章