发布时间:2023-01-06 文章分类:编程知识 投稿人:王小丽 字号: 默认 | | 超大 打印

简介

java.lang.reflect.Proxy是整个jdk中实现动态代理的核心 类,本文主要介绍Proxy类的实现,关于Proxy类的使用请自行查阅其他资料。

Field

private static final Class<?>[] constructorParams =
{ InvocationHandler.class };
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());

Inner Class

private static final class KeyFactory
implements BiFunction<ClassLoader, Class<?>[], Object>
{
@Override
public Object apply(ClassLoader classLoader, Class<?>[] interfaces) {
switch (interfaces.length) {
case 1: return new Key1(interfaces[0]); // the most frequent
case 2: return new Key2(interfaces[0], interfaces[1]);
case 0: return key0;
default: return new KeyX(interfaces);
}
}
}

由以上代码可见,该类的实现分为委托给了Key0,Key1,Key2,KeyX这四个类实现,其中key0是一个Object,其他的类Key1,Key2,KeyX则是分别用不同的实现对hashcode和equals方法进行了不同的实现,大同小异。这里则分别简单的做一下解释。

private static final class Key1 extends WeakReference<Class<?>> {
private final int hash;

Key1(Class<?> intf) {
super(intf);
this.hash = intf.hashCode();
}

@Override
public int hashCode() {
return hash;
}

@Override
public boolean equals(Object obj) {
Class<?> intf;
return this == obj ||
obj != null &&
obj.getClass() == Key1.class &&
(intf = get()) != null &&
intf == ((Key1) obj).get();
}
}
private static final class Key2 extends WeakReference<Class<?>> {
private final int hash;
private final WeakReference<Class<?>> ref2;

Key2(Class<?> intf1, Class<?> intf2) {
super(intf1);
hash = 31 * intf1.hashCode() + intf2.hashCode();
ref2 = new WeakReference<Class<?>>(intf2);
}

@Override
public int hashCode() {
return hash;
}

@Override
public boolean equals(Object obj) {
Class<?> intf1, intf2;
return this == obj ||
obj != null &&
obj.getClass() == Key2.class &&
(intf1 = get()) != null &&
intf1 == ((Key2) obj).get() &&
(intf2 = ref2.get()) != null &&
intf2 == ((Key2) obj).ref2.get();
}
}
private static final class KeyX {
private final int hash;
private final WeakReference<Class<?>>[] refs;

@SuppressWarnings("unchecked")
KeyX(Class<?>[] interfaces) {
hash = Arrays.hashCode(interfaces);
refs = (WeakReference<Class<?>>[])new WeakReference<?>[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
refs[i] = new WeakReference<>(interfaces[i]);
}
}

@Override
public int hashCode() {
return hash;
}

@Override
public boolean equals(Object obj) {
return this == obj ||
obj != null &&
obj.getClass() == KeyX.class &&
equals(refs, ((KeyX) obj).refs);
}

private static boolean equals(WeakReference<Class<?>>[] refs1,
WeakReference<Class<?>>[] refs2) {
if (refs1.length != refs2.length) {
return false;
}
for (int i = 0; i < refs1.length; i++) {
Class<?> intf = refs1[i].get();
if (intf == null || intf != refs2[i].get()) {
return false;
}
}
return true;
}
}
private static final class ProxyClassFactory
implements BiFunction<ClassLoader, Class<?>[], Class<?>>
{
// 代理类名称的前缀,我们看到的代理类的名称都有这个前缀就是这个原因
private static final String proxyClassNamePrefix = "$Proxy";

// 用于生成代理类名称的唯一的序号
private static final AtomicLong nextUniqueNumber = new AtomicLong();

@Override
public Class<?> apply(ClassLoader loader, Class<?>[] interfaces) {

Map<Class<?>, Boolean> interfaceSet = new IdentityHashMap<>(interfaces.length);
for (Class<?> intf : interfaces) {
/*
* 验证类加载器是否将此接口的名称解析为同一类对象
*/
Class<?> interfaceClass = null;
try {
interfaceClass = Class.forName(intf.getName(), false, loader);
} catch (ClassNotFoundException e) {
}
if (interfaceClass != intf) {
throw new IllegalArgumentException(
intf + " is not visible from class loader");
}
/*
* 验证此类实际是否是一个接口
*/
if (!interfaceClass.isInterface()) {
throw new IllegalArgumentException(
interfaceClass.getName() + " is not an interface");
}
/*
* 校验接口是不重复的
*/
if (interfaceSet.put(interfaceClass, Boolean.TRUE) != null) {
throw new IllegalArgumentException(
"repeated interface: " + interfaceClass.getName());
}
}
// 代理类包名
String proxyPkg = null;
//代理类的访问修饰符
int accessFlags = Modifier.PUBLIC | Modifier.FINAL;

/*
* 记录非public的代理接口的包,以至于代理类的定义是相同的包,验证所有的非public的代理接口在相同的包中。
*/
for (Class<?> intf : interfaces) {
int flags = intf.getModifiers();
if (!Modifier.isPublic(flags)) {
accessFlags = Modifier.FINAL;
String name = intf.getName();
int n = name.lastIndexOf('.');
String pkg = ((n == -1) ? "" : name.substring(0, n + 1));