From 3d0e02551685d54e0404925eeb02e254a23387dc Mon Sep 17 00:00:00 2001 From: wentch <22250530@qq.com> Date: Thu, 24 Dec 2015 15:23:45 +0800 Subject: [PATCH] --- src/org/redkale/convert/ObjectEncoder.java | 3 +- .../redkale/service/CacheSourceService.java | 16 ++--- src/org/redkale/util/Creator.java | 65 ++++++++++++++----- src/org/redkale/watch/WatchNumber.java | 6 +- 4 files changed, 59 insertions(+), 31 deletions(-) diff --git a/src/org/redkale/convert/ObjectEncoder.java b/src/org/redkale/convert/ObjectEncoder.java index 2bff1c693..843de1b46 100644 --- a/src/org/redkale/convert/ObjectEncoder.java +++ b/src/org/redkale/convert/ObjectEncoder.java @@ -5,7 +5,6 @@ */ package org.redkale.convert; -import java.beans.*; import org.redkale.util.Attribute; import java.lang.reflect.*; import java.util.*; @@ -241,7 +240,7 @@ public final class ObjectEncoder implements Encodeable implem this(cacheType, expireSeconds, (int) (System.currentTimeMillis() / 1000), key, value); } - private CacheEntry(CacheEntryType cacheType, int expireSeconds, int lastAccessed, K key, T value) { + @ConstructorProperties({"cacheType", "expireSeconds", "lastAccessed", "key", "value"}) + protected CacheEntry(CacheEntryType cacheType, int expireSeconds, int lastAccessed, K key, T value) { this.cacheType = cacheType; this.expireSeconds = expireSeconds; this.lastAccessed = lastAccessed; @@ -437,19 +439,11 @@ public class CacheSourceService implem this.value = value; } - protected static Creator createCreator() { //供 Creator.create 调用 - return (Creator) (Object... params) -> new CacheEntry((CacheEntryType) params[0], (Integer) params[1], (Integer) params[2], (Serializable) params[3], params[4]); - } - @Override public String toString() { return JsonFactory.root().getConvert().convertTo(this); } - public CacheEntryType getCacheType() { - return cacheType; - } - @Ignore public boolean isListCacheType() { return cacheType == CacheEntryType.LIST; @@ -465,6 +459,10 @@ public class CacheSourceService implem return (expireSeconds > 0 && lastAccessed + expireSeconds < (System.currentTimeMillis() / 1000)); } + public CacheEntryType getCacheType() { + return cacheType; + } + public int getExpireSeconds() { return expireSeconds; } diff --git a/src/org/redkale/util/Creator.java b/src/org/redkale/util/Creator.java index f988378e7..898bcd034 100644 --- a/src/org/redkale/util/Creator.java +++ b/src/org/redkale/util/Creator.java @@ -4,7 +4,10 @@ */ 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 jdk.internal.org.objectweb.asm.*; @@ -22,20 +25,35 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*; * * private String name; * - * public Record(int id, String name) { + * Record(int id, String name) { * this.id = id; * this.name = name; * } * * private static Creator createCreator() { - * return new Creator() { + * return new Creator() { * @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,10 +61,18 @@ import static jdk.internal.org.objectweb.asm.Opcodes.*; */ public interface Creator { + @Documented + @Target({CONSTRUCTOR, TYPE}) + @Retention(RUNTIME) + public static @interface ConstructorParameters { + + String[] value(); + } + public T create(Object... params); @SuppressWarnings("unchecked") - public static Creator create(Class clazz) { + public static Creator create(Class clazz) { if (clazz.isAssignableFrom(ArrayList.class)) { clazz = (Class) ArrayList.class; } else if (clazz.isAssignableFrom(HashMap.class)) { @@ -62,7 +88,7 @@ public interface Creator { if (method.getParameterTypes().length != 0) continue; if (method.getReturnType() != Creator.class) continue; try { - method.setAccessible(true); + method.setAccessible(true); return (Creator) method.invoke(null); } catch (Exception e) { throw new RuntimeException(e); @@ -89,14 +115,15 @@ public interface Creator { } } 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; @@ -106,16 +133,6 @@ public interface Creator { {//构造方法 mv = cw.visitMethod(ACC_PUBLIC, "", "()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", "", "()V", false); mv.visitInsn(RETURN); @@ -124,6 +141,18 @@ public interface Creator { } {//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); //--------------------------------------- diff --git a/src/org/redkale/watch/WatchNumber.java b/src/org/redkale/watch/WatchNumber.java index f5a903b2d..e475c55e5 100644 --- a/src/org/redkale/watch/WatchNumber.java +++ b/src/org/redkale/watch/WatchNumber.java @@ -5,6 +5,7 @@ */ package org.redkale.watch; +import java.beans.*; import java.util.concurrent.atomic.*; /** @@ -20,11 +21,12 @@ public final class WatchNumber extends AtomicLong implements WatchNode { private final String description; - WatchNumber(String name, String description, boolean interval, long v) { + @ConstructorProperties({"name", "description", "interval", "value"}) + protected WatchNumber(String name, String description, boolean interval, long value) { this.name = name; this.description = description; this.interval = interval; - this.set(v); + this.set(value); } @Override