This commit is contained in:
wentch
2016-01-22 10:30:36 +08:00
parent faa02b4b80
commit b1e2b118eb

View File

@@ -5,10 +5,12 @@
package org.redkale.util; package org.redkale.util;
import java.beans.*; import java.beans.*;
import java.io.*;
import java.lang.annotation.*; import java.lang.annotation.*;
import static java.lang.annotation.ElementType.*; import static java.lang.annotation.ElementType.*;
import static java.lang.annotation.RetentionPolicy.RUNTIME; import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.reflect.*; import java.lang.reflect.*;
import java.net.*;
import java.util.*; import java.util.*;
import jdk.internal.org.objectweb.asm.*; import jdk.internal.org.objectweb.asm.*;
import jdk.internal.org.objectweb.asm.Type; import jdk.internal.org.objectweb.asm.Type;
@@ -132,13 +134,13 @@ public interface Creator<T> {
} catch (Exception ex) { } catch (Exception ex) {
} }
Constructor<T> constructor0 = null; Constructor<T> constructor0 = null;
for (Constructor c : clazz.getConstructors()) { for (Constructor c : clazz.getConstructors()) { //优先找public 的构造函数
if (c.getParameterTypes().length == 0) { //为了兼容android 而不使用 getParameterCount() if (c.getParameterTypes().length == 0) { //为了兼容android 而不使用 getParameterCount()
constructor0 = c; constructor0 = c;
break; break;
} }
} }
if (constructor0 == null) { if (constructor0 == null) {//其次找非private带ConstructorProperties的构造函数
for (Constructor c : clazz.getDeclaredConstructors()) { for (Constructor c : clazz.getDeclaredConstructors()) {
if (Modifier.isPrivate(c.getModifiers())) continue; if (Modifier.isPrivate(c.getModifiers())) continue;
if (c.getAnnotation(ConstructorProperties.class) != null) { if (c.getAnnotation(ConstructorProperties.class) != null) {
@@ -147,6 +149,13 @@ public interface Creator<T> {
} }
} }
} }
if (constructor0 == null) {//最后找非private的构造函数
for (Constructor c : clazz.getDeclaredConstructors()) {
if (Modifier.isPrivate(c.getModifiers())) continue;
constructor0 = c;
break;
}
}
final Constructor<T> constructor = constructor0; final Constructor<T> constructor = constructor0;
if (constructor == null) throw new RuntimeException("[" + clazz + "] have no public or java.beans.ConstructorProperties-Annotation constructor."); if (constructor == null) throw new RuntimeException("[" + clazz + "] have no public or java.beans.ConstructorProperties-Annotation constructor.");
//------------------------------------------------------------- //-------------------------------------------------------------
@@ -270,9 +279,37 @@ public interface Creator<T> {
} }
cw.visitEnd(); cw.visitEnd();
final byte[] bytes = cw.toByteArray(); final byte[] bytes = cw.toByteArray();
final boolean ispub = Modifier.isPublic(constructor.getModifiers());
Class<?> resultClazz = null;
if (loader instanceof URLClassLoader && !ispub) {
try { try {
if (!Modifier.isPublic(constructor.getModifiers())) throw new RuntimeException("[" + clazz + "] have no public or java.beans.ConstructorProperties-Annotation constructor."); final URLClassLoader urlLoader = (URLClassLoader) loader;
Class<?> resultClazz = new ClassLoader(loader) { final URL url = new URL("memclass", "localhost", -1, "/" + newDynName.replace('/', '.') + "/", new URLStreamHandler() {
@Override
protected URLConnection openConnection(URL u) throws IOException {
return new URLConnection(u) {
@Override
public void connect() throws IOException {
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(bytes);
}
};
}
});
Method addURLMethod = URLClassLoader.class.getDeclaredMethod("addURL", URL.class);
addURLMethod.setAccessible(true);
addURLMethod.invoke(urlLoader, url);
resultClazz = urlLoader.loadClass(newDynName.replace('/', '.'));
} catch (Throwable t) { //异常无需理会, 使用下一种loader方式
t.printStackTrace();
}
}
try {
if (!ispub) throw new RuntimeException("[" + clazz + "] have no public or java.beans.ConstructorProperties-Annotation constructor.");
if (resultClazz == null) resultClazz = new ClassLoader(loader) {
public final Class<?> loadClass(String name, byte[] b) { public final Class<?> loadClass(String name, byte[] b) {
return defineClass(name, b, 0, b.length); return defineClass(name, b, 0, b.length);
} }