SpringAOP的實現(xiàn)有 jdk 動態(tài)代理和 cglib 代理贱纠,對應(yīng)的核心類是 JdkDynamicAopProxy 和CglibAopProxy皆看。
先來看 JdkDynamicAopProxy偏陪,找到它的 invoke方法,上碼:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
// 最終操作的是 TargetSource對象
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
// 不代理 equals 和 hashCode 方法赐稽,調(diào)用 JdkDynamicAopProxy中的equal比較和hashCode方法
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// 如果 method是在 advised中聲明的瞧哟,則把 method轉(zhuǎn)到 advised對象中使用
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
if (this.advised.exposeProxy) {
// 如果暴露代理對象亭引,則把proxy設(shè)置到 ThreadLocal 中贞岭,線程內(nèi)可共享該對象
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
target = targetSource.getTarget();
Class<?> targetClass = (target != null ? target.getClass() : null);
// 獲取方法的攔截器鏈
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
if (chain.isEmpty()) {
// 攔截器鏈為空八毯,則適配參數(shù),直接調(diào)用目標方法
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
// 創(chuàng)建 ReflectiveMethodInvocation瞄桨,去執(zhí)行前置话速、后置等增強器
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 驅(qū)動執(zhí)行所有攔截器
retVal = invocation.proceed();
}
// 返回值處理
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy)
&&!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
" ……");
}
return retVal;
}
finally {
……
}
我們來重點分析 ReflectiveMethodInvocation#proceed() 方法:
public Object proceed() throws Throwable {
// 攔截器執(zhí)行完了,就執(zhí)行目標對象的目標方法
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();
}
// 獲取責任鏈下一個 MethodInterceptor, 對目標方法進行增強處理
Object interceptorOrInterceptionAdvice =this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
InterceptorAndDynamicMethodMatcher dm =(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
// 方法動態(tài)匹配成功芯侥,才進行增強處理
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);
}
else {
// 動態(tài)匹配失敗泊交,跳過當前攔截器乳讥,跳到下一個
return proceed();
}
}
else {
// 不需要動態(tài)匹配,則直接調(diào)用 MethodInterceptor 的invoke方法
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
}
}
我們來看 ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this) 廓俭,這里是每個interceptor都去invoke一遍云石,我們先看 MethodBeforeAdviceInterceptor#invoke()
public class MethodBeforeAdviceInterceptor implements MethodInterceptor, BeforeAdvice, Serializable {
private final MethodBeforeAdvice advice;
public MethodBeforeAdviceInterceptor(MethodBeforeAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
// 先執(zhí)行 MethodBeforeAdvice 這個 advice,而advice.before 的這個before,
//正是我們定義的前置通知的方法體
this.advice.before(mi.getMethod(), mi.getArguments(), mi.getThis());
// 再遞歸執(zhí)行 MethodInvocation
return mi.proceed();
}
}
接著再來看 AfterReturningAdviceInterceptor#invoke()
public class AfterReturningAdviceInterceptor implements MethodInterceptor, AfterAdvice, Serializable {
private final AfterReturningAdvice advice;
public AfterReturningAdviceInterceptor(AfterReturningAdvice advice) {
Assert.notNull(advice, "Advice must not be null");
this.advice = advice;
}
@Override
@Nullable
public Object invoke(MethodInvocation mi) throws Throwable {
//先執(zhí)行中間的 MethodInvocation研乒,比如 目標方法
Object retVal = mi.proceed();
// 再執(zhí)行 AfterReturningAdvice advice的 afterReturning(),這個
// afterReturning() 就是我們定義的后置處理的方法體
this.advice.afterReturning(retVal, mi.getMethod(), mi.getArguments(), mi.getThis());
return retVal;
}
}
各位看官汹忠,到這里是不是很明了了。簡而言之雹熬,就是遍歷所有的增強器(攔截器)宽菜,有前置增強器就先執(zhí)行它,接著執(zhí)行目標方法竿报,再執(zhí)行后置增強器铅乡。就是辣么竿丹~~
CglibAopProxy 也類似,最終也是調(diào)用 ReflectiveMethodInvocation#proceed()~~
各位看官烈菌,下節(jié)更精彩阵幸,點個贊,年薪百萬不是夢~