簡介
java.lang.reflect.Proxy是整個jdk中實作動態代理的核心 類,本文主要介紹Proxy類的實作,關于Proxy類的使用請自行查閱其他資料,
Field
-
constructorParams:建構式的引數,用于代理類的核心的邏輯實作,關于InvocationHandler這個介面的介紹不是本文的重點,此處不做介紹,
private static final Class<?>[] constructorParams =
{ InvocationHandler.class };
-
proxyClassCache: 代理類的快取,此類是一個二級快取的實作,利用WeakReference的特性,當記憶體占用過高的時候會JVM自動進行回收快取中的資料,
private static final WeakCache<ClassLoader, Class<?>[], Class<?>>
proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
-
h: InvocationHandler介面,用于此代理實體的呼叫處理程式,
Inner Class
-
KeyFactory:顧名思義,快取代理的key的工廠實作,此類僅一個方法,實作了BiFunction介面,具體代碼如下
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;
}
}
-
ProxyClassFactory: 顧名思義, 代理類的生產工廠類,用于生成代理類,此類也是實作了BiFunction,技能一個apply方法,最終根據ClassLoader,Interface,proxyName引數呼叫java.lang.reflect.Proxy#defineClass0這個本地方法生成代理類,
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));
if (proxyPkg == null) {
proxyPkg 