Spring使用JDK动态代理或者CGLIB的方式来生成代理对象,其中每个代理对象都会实现SpringProxy接口。具体原理请接着往下看:
JDK动态代理创建代理的方法如下所示:
public Object getProxy(@Nullable ClassLoader classLoader) {
....
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
}
下面是CGLIB创建代理的方法:
@Override
public Object getProxy(@Nullable ClassLoader classLoader) {
....
// Configure CGLIB Enhancer...
Enhancer enhancer = createEnhancer();
if (classLoader != null) {
enhancer.setClassLoader(classLoader);
if (classLoader instanceof SmartClassLoader &&
((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
enhancer.setUseCache(false);
}
}
enhancer.setSuperclass(proxySuperClass);
enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));
....
}
无论是哪一种方式,都调用了以下的方法
AopProxyUtils.completeProxiedInterfaces(this.advised)
该方法的作用是:根据Advised对象获取代理对象需要实现的接口列表。
代码如下所示:
static Class<?>[] completeProxiedInterfaces(AdvisedSupport advised, boolean decoratingProxy) {
...
//advised.isInterfaceProxied(SpringProxy.class)表示代理对象本来实现的接口列表中是否包含SpringProxy接口
boolean addSpringProxy = !advised.isInterfaceProxied(SpringProxy.class);
...
Class<?>[] proxiedInterfaces = new Class<?>[specifiedInterfaces.length + nonUserIfcCount];
...
//如果接口列表不包含SpringProxy接口,动态添加SpringProxy接口,所以代理对象始终会实现SpringProxy接口
if (addSpringProxy) {
proxiedInterfaces[index] = SpringProxy.class;
index++;
}
return proxiedInterfaces;
}
在这个方法中给代理对象需要实现的接口列表proxiedInterfaces中动态添加了SpringProxy接口,所以经过spring创建的代理对象都将实现SpringProxy接口。