This commit is contained in:
@@ -5,7 +5,6 @@
|
||||
*/
|
||||
package org.redkale.convert;
|
||||
|
||||
import java.beans.*;
|
||||
import org.redkale.util.Attribute;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
@@ -242,7 +241,7 @@ public final class ObjectEncoder<W extends Writer, T> implements Encodeable<W, T
|
||||
|
||||
static String[] findConstructorProperties(Creator creator) {
|
||||
try {
|
||||
ConstructorProperties cps = creator.getClass().getConstructor().getAnnotation(ConstructorProperties.class);
|
||||
Creator.ConstructorParameters cps = creator.getClass().getMethod("create", Object[].class).getAnnotation(Creator.ConstructorParameters.class);
|
||||
return cps == null ? null : cps.value();
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
|
||||
@@ -4,9 +4,13 @@
|
||||
*/
|
||||
package org.redkale.util;
|
||||
|
||||
import java.beans.ConstructorProperties;
|
||||
import java.beans.*;
|
||||
import java.lang.annotation.*;
|
||||
import static java.lang.annotation.ElementType.*;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
import java.lang.reflect.*;
|
||||
import java.util.*;
|
||||
|
||||
import org.objectweb.asm.*;
|
||||
import static org.objectweb.asm.Opcodes.*;
|
||||
import org.objectweb.asm.Type;
|
||||
@@ -22,7 +26,7 @@ import org.objectweb.asm.Type;
|
||||
*
|
||||
* private String name;
|
||||
*
|
||||
* public Record(int id, String name) {
|
||||
* Record(int id, String name) {
|
||||
* this.id = id;
|
||||
* this.name = name;
|
||||
* }
|
||||
@@ -30,12 +34,27 @@ import org.objectweb.asm.Type;
|
||||
* private static Creator createCreator() {
|
||||
* return new Creator<Record>() {
|
||||
* @Override
|
||||
* @ConstructorParameters({"id", "name"})
|
||||
* public Record create(Object... params) {
|
||||
* return new Record((Integer) params[0], (String) params[1]);
|
||||
* }
|
||||
* };
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* 或者:
|
||||
* public class Record {
|
||||
*
|
||||
* private final int id;
|
||||
*
|
||||
* private String name;
|
||||
*
|
||||
* @ConstructorProperties({"id", "name"})
|
||||
* public Record(int id, String name) {
|
||||
* this.id = id;
|
||||
* this.name = name;
|
||||
* }
|
||||
* }
|
||||
*
|
||||
* @see http://www.redkale.org
|
||||
* @author zhangjx
|
||||
@@ -43,9 +62,17 @@ import org.objectweb.asm.Type;
|
||||
*/
|
||||
public interface Creator<T> {
|
||||
|
||||
@Documented
|
||||
@Target({CONSTRUCTOR, TYPE})
|
||||
@Retention(RUNTIME)
|
||||
public static @interface ConstructorParameters {
|
||||
|
||||
String[] value();
|
||||
}
|
||||
|
||||
public T create(Object... params);
|
||||
|
||||
public static abstract class Creators {
|
||||
public abstract class Creators {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Creator<T> create(Class<T> clazz) {
|
||||
@@ -64,7 +91,7 @@ public interface Creator<T> {
|
||||
if (method.getParameterTypes().length != 0) continue;
|
||||
if (method.getReturnType() != Creator.class) continue;
|
||||
try {
|
||||
method.setAccessible(true);
|
||||
method.setAccessible(true);
|
||||
return (Creator<T>) method.invoke(null);
|
||||
} catch (Exception e) {
|
||||
throw new RuntimeException(e);
|
||||
@@ -91,33 +118,24 @@ public interface Creator<T> {
|
||||
}
|
||||
}
|
||||
if (constructor == null) {
|
||||
for (Constructor c : clazz.getConstructors()) {
|
||||
if (c.getAnnotation(ConstructorProperties.class) != null) {
|
||||
for (Constructor c : clazz.getDeclaredConstructors()) {
|
||||
if (Modifier.isPrivate(c.getModifiers())) continue;
|
||||
if (c.getAnnotation(ConstructorProperties.class) != null || c.getAnnotation(ConstructorParameters.class) != null) {
|
||||
constructor = c;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
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 or ConstructorParameters-Annotation constructor.");
|
||||
//-------------------------------------------------------------
|
||||
ClassWriter cw = new ClassWriter(0);
|
||||
FieldVisitor fv;
|
||||
MethodVisitor mv;
|
||||
AnnotationVisitor av0;
|
||||
cw.visit(V1_7, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, "Ljava/lang/Object;L" + supDynName + "<" + interDesc + ">;", "java/lang/Object", new String[]{supDynName});
|
||||
cw.visit(V1_8, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, "Ljava/lang/Object;L" + supDynName + "<" + interDesc + ">;", "java/lang/Object", new String[]{supDynName});
|
||||
|
||||
{//构造方法
|
||||
mv = cw.visitMethod(ACC_PUBLIC, "<init>", "()V", null, null);
|
||||
ConstructorProperties cps = constructor.getAnnotation(ConstructorProperties.class);
|
||||
if (cps != null) {
|
||||
av0 = mv.visitAnnotation(Type.getDescriptor(ConstructorProperties.class), true);
|
||||
AnnotationVisitor av1 = av0.visitArray("value");
|
||||
for (String n : cps.value()) {
|
||||
av1.visit(null, n);
|
||||
}
|
||||
av1.visitEnd();
|
||||
av0.visitEnd();
|
||||
}
|
||||
mv.visitVarInsn(ALOAD, 0);
|
||||
mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false);
|
||||
mv.visitInsn(RETURN);
|
||||
@@ -126,6 +144,18 @@ public interface Creator<T> {
|
||||
}
|
||||
{//create 方法
|
||||
mv = cw.visitMethod(ACC_PUBLIC + ACC_VARARGS, "create", "([Ljava/lang/Object;)L" + interName + ";", null, null);
|
||||
ConstructorProperties cps = constructor.getAnnotation(ConstructorProperties.class);
|
||||
ConstructorParameters cts = constructor.getAnnotation(ConstructorParameters.class);
|
||||
final String[] cparams = cps == null ? (cts == null ? null : cts.value()) : cps.value();
|
||||
if (cparams != null) {
|
||||
av0 = mv.visitAnnotation(Type.getDescriptor(ConstructorParameters.class), true);
|
||||
AnnotationVisitor av1 = av0.visitArray("value");
|
||||
for (String n : cps.value()) {
|
||||
av1.visit(null, n);
|
||||
}
|
||||
av1.visitEnd();
|
||||
av0.visitEnd();
|
||||
}
|
||||
mv.visitTypeInsn(NEW, interName);
|
||||
mv.visitInsn(DUP);
|
||||
//---------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user