代理对象调用过程
代理对象的调用是通过反射的方式调用的(另外一种这里暂且不论),JdkDynamicAopProxy#invoke
,方法中先处理了是否要暴露代理对象的处理,如下:
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
static Object setCurrentProxy(@Nullable Object proxy) {
Object old = currentProxy.get();
if (proxy != null) {
currentProxy.set(proxy);
}
else {
currentProxy.remove();
}
return old;
}
private static final ThreadLocal<Object> currentProxy = new NamedThreadLocal<>("Current AOP proxy");
当exposeProxy
为 true
时,会把对象添加到ThreadLocal
中,在本线程中暴露出去,解决类中方法相互调用的问题。
然后获取方法上的拦截器链:
// Get the interception chain for this method.
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
|- MethodInterceptor[] interceptors = registry.getInterceptors(advisor);
没有时,会遍历一遍增强器链,用方法匹配器去匹配一下,看看是否适配此方法,获取到满足的方法拦截器,并组成拦截器链,然后加载到缓存中
private transient Map<MethodCacheKey, List<Object>> methodCache;
如果链为空,则直接反射调用就行了
如果不为空,则创建一个ReflectiveMethodInvocation
调用对象,进行链路调用,每次通过++currentInterceptorIndex
索引获取增强器,构成链式调用。如下图: