Spring源代码解析(七):Spring AOP中对拦截器调用的实现
时间:2011-03-29 javaeye jiwenke
前面我们分析了Spring AOP实现中得到Proxy对象的过程,下面我们看看在Spring AOP 中拦截器链是怎样被调用的,也就是Proxy模式是怎样起作用的,或者说Spring是怎样为 我们提供AOP功能的;
在JdkDynamicAopProxy中生成Proxy对象的时候:
Java代码
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
这里的this参数对应的是InvocationHandler对象,这里我们的JdkDynamicAopProxy实 现了这个接口,也就是说当Proxy对象的函数被调用的时候,这个InvocationHandler的 invoke方法会被作为回调函数调用,下面我们看看这个方法的实现:
Java代码
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
MethodInvocation invocation = null;
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Class targetClass = null;
Object target = null;
try {
// Try special rules for equals() method and implementation of the
// Advised AOP configuration interface.
if (!this.equalsDefined && AopUtils.isEqualsMethod (method)) {
// What if equals throws exception!?
// This class implements the equals(Object) method itself.
return equals(args[0]) ? Boolean.TRUE : Boolean.FALSE;
}
if (!this.hashCodeDefined && AopUtils.isHashCodeMethod (method)) {
// This class implements the hashCode() method itself.
return new Integer(hashCode());
}
if (Advised.class == method.getDeclaringClass()) {
// service invocations on ProxyConfig with the proxy config
return AopUtils.invokeJoinpointUsingReflection (this.advised, method, args);
}
Object retVal = null;
if (this.advised.exposeProxy) {
// make invocation available if necessary
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// May be <code>null</code>. Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
// 这里是得到目标对象的地方,当然这个目标对象可能来自于一个实例 池或者是一个简单的JAVA对象
target = targetSource.getTarget();
if (target != null) {
targetClass = target.getClass();
}
// get the interception chain for this method
// 这里获得定义好的拦截器链
List chain = this.advised.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice (
this.advised, proxy, method, targetClass);
// Check whether we have any advice. If we don''t, we can fallback on direct
// reflective invocation of the target, and avoid creating a Method
|