介绍常用的 Advice

AspectJMethodBeforeAdvice, AspectJAfterReturningAdvice 没有实现 MethodInterceptor 接口, 在构造调用链时会通过 MethodBeforeAdviceAdapter, AfterReturningAdviceAdapter 这两个适配器转换成对应的接口,通过调用 MethodInterceptor#invoke 方法来实现对各个方法的处理
AspectJMethodBeforeAdvice
定位: org.springframework.aop.framework.adapter.MethodBeforeAdviceInterceptor#invoke
1 2 3 4 5 6 7 8
| @Override public Object invoke(MethodInvocation mi) throws Throwable { this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis()); return mi.proceed(); }
|
定位: org.springframework.aop.aspectj.AspectJMethodBeforeAdvice#before
1 2 3 4
| public void before(Method method, Object[] args, @Nullable Object target) throws Throwable { invokeAdviceMethod(getJoinPointMatch(), null, null); }
|
AspectJAfterReturningAdvice
定位: org.springframework.aop.framework.adapter.AfterReturningAdviceInterceptor
1 2 3 4 5 6 7
| public Object invoke(MethodInvocation mi) throws Throwable { Object retVal = mi.proceed(); this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis()); return retVal; }
|
定位: org.springframework.aop.aspectj.AspectJAfterReturningAdvice#afterReturning
1 2 3 4 5
| public void afterReturning(@Nullable Object returnValue, Method method, Object[] args, @Nullable Object target) throws Throwable { if (shouldInvokeOnReturnValueOf(method, returnValue)) { invokeAdviceMethod(getJoinPointMatch(), returnValue, null); } }
|
AspectJAfterThrowingAdvice
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public Object invoke(MethodInvocation mi) throws Throwable { try { return mi.proceed(); } catch (Throwable ex) { if (shouldInvokeOnThrowing(ex)) { invokeAdviceMethod(getJoinPointMatch(), null, ex); } throw ex; } }
|
AspectJAfterAdvice
1 2 3 4 5 6 7 8 9 10 11
| @Override public Object invoke(MethodInvocation mi) throws Throwable { try { return mi.proceed(); } finally { invokeAdviceMethod(getJoinPointMatch(), null, null); } }
|
AspectJAroundAdvice
1 2 3 4 5 6 7 8 9 10
| @Override public Object invoke(MethodInvocation mi) throws Throwable { if (!(mi instanceof ProxyMethodInvocation)) { throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi); } ProxyMethodInvocation pmi = (ProxyMethodInvocation) mi; ProceedingJoinPoint pjp = lazyGetProceedingJoinPoint(pmi); JoinPointMatch jpm = getJoinPointMatch(pmi); return invokeAdviceMethod(pjp, jpm, null, null); }
|
AbstractAspectJAdvice
invokeAdviceMethod
定位: org.springframework.aop.aspectj.AbstractAspectJAdvice#invokeAdviceMethod
调用 advice 方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
| protected Object invokeAdviceMethod(JoinPoint jp, @Nullable JoinPointMatch jpMatch, @Nullable Object returnValue, @Nullable Throwable t) throws Throwable {
return invokeAdviceMethodWithGivenArgs(argBinding(jp, jpMatch, returnValue, t)); } protected Object invokeAdviceMethodWithGivenArgs(Object[] args) throws Throwable { Object[] actualArgs = args; if (this.aspectJAdviceMethod.getParameterCount() == 0) { actualArgs = null; } try { ReflectionUtils.makeAccessible(this.aspectJAdviceMethod); return this.aspectJAdviceMethod.invoke(this.aspectInstanceFactory.getAspectInstance(), actualArgs); } 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(); } }
|
getJoinPointMatch
定位: org.springframework.aop.aspectj.AbstractAspectJAdvice#getJoinPointMatch
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| protected JoinPointMatch getJoinPointMatch() { MethodInvocation mi = ExposeInvocationInterceptor.currentInvocation(); if (!(mi instanceof ProxyMethodInvocation)) { throw new IllegalStateException("MethodInvocation is not a Spring ProxyMethodInvocation: " + mi); } return getJoinPointMatch((ProxyMethodInvocation) mi); } protected JoinPointMatch getJoinPointMatch(ProxyMethodInvocation pmi) { String expression = this.pointcut.getExpression(); return (expression != null ? (JoinPointMatch) pmi.getUserAttribute(expression) : null); }
|