为了说明ClassLoader策略如此重要,以Spring框架中AopProxy为例:
这个AopProxy是所有代理实现的总接口,代理实现有jdk动态代理或cglib代理等。
public interface AopProxy {
/**
* Creates a new Proxy object for the given object, proxying
* the given interface. Uses the thread context class loader.
*/
public abstract Object getProxy();
/**
* Creates a new Proxy object for the given object, proxying
* the given interface. Uses the given class loader.
*/
public abstract Object getProxy(ClassLoader cl);
}
上面两个方法都是充分重视ClassLoader。
我们看看JdkDynamicAopProxy的一个实现是如何制定ClassLoader策略的:
public Object getProxy() {
return getProxy(Thread.currentThread().getContextClassLoader());
}
/**
* Create a new Proxy object for the given object, proxying
* the given interface. Uses the given class loader.
*/
public Object getProxy(ClassLoader cl) {
if (logger.isDebugEnabled()) {
logger.debug("Creating JDK dynamic proxy for [" + this.advised.getTargetSource().getTargetClass() + "]");
}
Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
return Proxy.newProxyInstance(cl, proxiedInterfaces, this);
}
注意这里策略是使用Thread.currentThread().getContextClassLoader(),而不是普通的Class.forName();
欢迎对这些有兴趣者一起谈论。