测试用例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的通知
- *DemoApplication.main()
- *CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- *AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice()
- *DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()
- *DefaultAdvisorAdapterRegistry.getInterceptors()
- *MethodBeforeAdviceAdapter.getInterceptor()
- *MethodBeforeAdviceInterceptor.MethodBeforeAdviceInterceptor()
调用methodBefore前置通知
将断点打到TestAspect.methodBefore方法,则代码执行过程如下
代码块8:intercept
继续进行
参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)
参数:args=com.helloworld.entity.UserInfo@2e9fda69,
package org.springframework.aop.framework;
public class CglibAopProxy implements AopProxy{
@Override
@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前置通知
- DemoApplication.main()
- *CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- *ReflectiveMethodInvocation.proceed()
- *ExposeInvocationInterceptor.invoke()
- *ReflectiveMethodInvocation.proceed()
- *AspectJAfterAdvice.invoke()
- *ReflectiveMethodInvocation.proceed()
- *MethodBeforeAdviceInterceptor.invoke()
- *AspectJMethodBeforeAdvice.before()
- *AbstractAspectJAdvice.invokeAdviceMethod()
- *AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
- *TestAspect.methodBefore()
调用连接点方法
将断点打到UserServiceImpl.save方法,则代码执行过程如下
代码块19:invoke
继续进行
package org.springframework.aop.framework.adapter;
public class MethodBeforeAdviceInterceptor implements MethodInterceptor{
@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) 调用连接点方法"
}
}
小结:调用栈
调用连接点方法
- DemoApplication.main()
- CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- ReflectiveMethodInvocation.proceed()
- ExposeInvocationInterceptor.invoke()
- ReflectiveMethodInvocation.proceed()
- AspectJAfterAdvice.invoke()
- ReflectiveMethodInvocation.proceed()
- *MethodBeforeAdviceInterceptor.invoke()
- *ReflectiveMethodInvocation.proceed()
- *CglibAopProxy$CglibMethodInvocation.invokeJoinpoint()
- *MethodProxy.invoke()
- *UserServiceImpl.save()
调用methodAfter后置通知
将断点打到TestAspect.methodAfter方法,则代码执行过程如下
代码块24:proceed
调用通知方法
package org.springframework.aop.framework;
public class ReflectiveMethodInvocation implements ProxyMethodInvocation{
@Override
@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后置通知
- DemoApplication.main()
- CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- ReflectiveMethodInvocation.proceed()
- ExposeInvocationInterceptor.invoke()
- *ReflectiveMethodInvocation.proceed()
- *AbstractAspectJAdvice.invokeAdviceMethod()
- *AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
- *TestAspect.methodAfter()
完整代码版
下面执行userServiceImpl的save方法,首先获取userServiceImpl的通知
将断点打到MethodBeforeAdviceInterceptor.MethodBeforeAdviceInterceptor()方法,则代码执行过程如下
代码块1:main
拦截
参数:args=[]
package com.helloworld;
public class DemoApplication {
public static void main( String[] args ) {
//args=[];
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(DemoApplication.class);
UserService userService = (UserService) ctx.getBean("userServiceImpl");
UserInfo userInfo = (UserInfo) ctx.getBean("user_zhangsan");
userService.save(userInfo);
"(1) 拦截"
"参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)"
"参数:args=com.helloworld.entity.UserInfo@2e9fda69,"
}
}
代码块2:intercept
获取拦截器和动态拦截通知
参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)
参数:args=com.helloworld.entity.UserInfo@2e9fda69,
package org.springframework.aop.framework;
public class CglibAopProxy implements AopProxy{
@Override
@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的通知
- *DemoApplication.main()
- *CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- *AdvisedSupport.getInterceptorsAndDynamicInterceptionAdvice()
- *DefaultAdvisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice()
- *DefaultAdvisorAdapterRegistry.getInterceptors()
- *MethodBeforeAdviceAdapter.getInterceptor()
- *MethodBeforeAdviceInterceptor.MethodBeforeAdviceInterceptor()
调用methodBefore前置通知
将断点打到TestAspect.methodBefore方法,则代码执行过程如下
代码块8:intercept
继续进行
参数:method=public void com.helloworld.service.impl.UserServiceImpl.save(com.helloworld.entity.UserInfo)
参数:args=com.helloworld.entity.UserInfo@2e9fda69,
package org.springframework.aop.framework;
public class CglibAopProxy implements AopProxy{
@Override
@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前置通知
- DemoApplication.main()
- *CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- *ReflectiveMethodInvocation.proceed()
- *ExposeInvocationInterceptor.invoke()
- *ReflectiveMethodInvocation.proceed()
- *AspectJAfterAdvice.invoke()
- *ReflectiveMethodInvocation.proceed()
- *MethodBeforeAdviceInterceptor.invoke()
- *AspectJMethodBeforeAdvice.before()
- *AbstractAspectJAdvice.invokeAdviceMethod()
- *AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
- *TestAspect.methodBefore()
调用连接点方法
将断点打到UserServiceImpl.save方法,则代码执行过程如下
代码块19:invoke
继续进行
package org.springframework.aop.framework.adapter;
public class MethodBeforeAdviceInterceptor implements MethodInterceptor{
@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) 调用连接点方法"
}
}
小结:调用栈
调用连接点方法
- DemoApplication.main()
- CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- ReflectiveMethodInvocation.proceed()
- ExposeInvocationInterceptor.invoke()
- ReflectiveMethodInvocation.proceed()
- AspectJAfterAdvice.invoke()
- ReflectiveMethodInvocation.proceed()
- *MethodBeforeAdviceInterceptor.invoke()
- *ReflectiveMethodInvocation.proceed()
- *CglibAopProxy$CglibMethodInvocation.invokeJoinpoint()
- *MethodProxy.invoke()
- *UserServiceImpl.save()
调用methodAfter后置通知
将断点打到TestAspect.methodAfter方法,则代码执行过程如下
代码块24:proceed
调用通知方法
package org.springframework.aop.framework;
public class ReflectiveMethodInvocation implements ProxyMethodInvocation{
@Override
@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后置通知
- DemoApplication.main()
- CglibAopProxy$DynamicAdvisedInterceptor.intercept()
- ReflectiveMethodInvocation.proceed()
- ExposeInvocationInterceptor.invoke()
- *ReflectiveMethodInvocation.proceed()
- *AbstractAspectJAdvice.invokeAdviceMethod()
- *AbstractAspectJAdvice.invokeAdviceMethodWithGivenArgs()
- *TestAspect.methodAfter()