diff --git a/src/module-info.java b/src/module-info.java index 9e31830ad..549c6c0e2 100644 --- a/src/module-info.java +++ b/src/module-info.java @@ -6,7 +6,12 @@ * module org.redkale { - requires java.se; + requires java.base; + requires java.logging; + requires java.xml; + requires java.sql; + requires java.sql.rowset; + requires jdk.unsupported; //sun.misc.Unsafe exports javax.annotation; diff --git a/src/org/redkale/convert/ConvertFactory.java b/src/org/redkale/convert/ConvertFactory.java index 0866bf3a1..41f8765e0 100644 --- a/src/org/redkale/convert/ConvertFactory.java +++ b/src/org/redkale/convert/ConvertFactory.java @@ -119,7 +119,7 @@ public abstract class ConvertFactory { this.register(AnyValue.class, Creator.create(AnyValue.DefaultAnyValue.class)); this.register(HttpCookie.class, new Creator() { @Override - @Creator.ConstructorParameters({"name", "value"}) + @ConstructorParameters({"name", "value"}) public HttpCookie create(Object... params) { return new HttpCookie((String) params[0], (String) params[1]); } diff --git a/src/org/redkale/convert/ObjectEncoder.java b/src/org/redkale/convert/ObjectEncoder.java index 6f4f5d532..07da0a0df 100644 --- a/src/org/redkale/convert/ObjectEncoder.java +++ b/src/org/redkale/convert/ObjectEncoder.java @@ -207,7 +207,7 @@ public final class ObjectEncoder implements Encodeable", "(" + handlerDesc + ")V", null, null)); //mv.setDebug(true); { - av0 = mv.visitAnnotation("Ljava/beans/ConstructorProperties;", true); + av0 = mv.visitAnnotation("Lorg/redkale/util/ConstructorParameters;", true); { AnnotationVisitor av1 = av0.visitArray("value"); av1.visit(null, "handler"); diff --git a/src/org/redkale/net/sncp/SncpAsyncHandler.java b/src/org/redkale/net/sncp/SncpAsyncHandler.java index 4654f0839..7b7eb01d6 100644 --- a/src/org/redkale/net/sncp/SncpAsyncHandler.java +++ b/src/org/redkale/net/sncp/SncpAsyncHandler.java @@ -53,7 +53,7 @@ public interface SncpAsyncHandler extends CompletionHandler { * * private CompletableFuture sncpfuture; * - * @java.beans.ConstructorProperties({"sncphandler"}) + * @ConstructorParameters({"sncphandler"}) * public XXXAsyncHandler_DyncSncpAsyncHandler_4323(SncpAsyncHandler sncphandler) { * super(); * this.sncphandler = sncphandler; @@ -123,7 +123,7 @@ public interface SncpAsyncHandler extends CompletionHandler { mv = new AsmMethodVisitor(cw.visitMethod(ACC_PUBLIC, "", "(" + sncpHandlerDesc + ")V", null, null)); //mv.setDebug(true); { - av0 = mv.visitAnnotation("Ljava/beans/ConstructorProperties;", true); + av0 = mv.visitAnnotation("org/redkale/util/ConstructorParameters;", true); { AnnotationVisitor av1 = av0.visitArray("value"); av1.visit(null, "sncphandler"); diff --git a/src/org/redkale/source/CacheSource.java b/src/org/redkale/source/CacheSource.java index 59f553e21..7833e394a 100644 --- a/src/org/redkale/source/CacheSource.java +++ b/src/org/redkale/source/CacheSource.java @@ -5,12 +5,12 @@ */ package org.redkale.source; -import java.beans.ConstructorProperties; import java.lang.reflect.Type; import java.util.*; import java.util.concurrent.*; import org.redkale.convert.ConvertColumn; import org.redkale.convert.json.JsonFactory; +import org.redkale.util.ConstructorParameters; /** * @@ -248,7 +248,7 @@ public interface CacheSource { this(cacheType, expireSeconds, (int) (System.currentTimeMillis() / 1000), key, objectValue, csetValue, listValue); } - @ConstructorProperties({"cacheType", "expireSeconds", "lastAccessed", "key", "objectValue", "csetValue", "listValue"}) + @ConstructorParameters({"cacheType", "expireSeconds", "lastAccessed", "key", "objectValue", "csetValue", "listValue"}) public CacheEntry(CacheEntryType cacheType, int expireSeconds, int lastAccessed, String key, T objectValue, CopyOnWriteArraySet csetValue, ConcurrentLinkedQueue listValue) { this.cacheType = cacheType; this.expireSeconds = expireSeconds; diff --git a/src/org/redkale/source/EntityInfo.java b/src/org/redkale/source/EntityInfo.java index c6c0d034a..75c912a22 100644 --- a/src/org/redkale/source/EntityInfo.java +++ b/src/org/redkale/source/EntityInfo.java @@ -211,9 +211,9 @@ public final class EntityInfo { this.tableStrategy = dts; this.creator = Creator.create(type); - Creator.ConstructorParameters cp = null; + ConstructorParameters cp = null; try { - cp = this.creator.getClass().getMethod("create", Object[].class).getAnnotation(Creator.ConstructorParameters.class); + cp = this.creator.getClass().getMethod("create", Object[].class).getAnnotation(ConstructorParameters.class); } catch (Exception e) { logger.log(Level.SEVERE, type + " cannot find ConstructorParameters Creator", e); } diff --git a/src/org/redkale/source/FilterKey.java b/src/org/redkale/source/FilterKey.java index edf6d2ee0..b0a1b52fb 100644 --- a/src/org/redkale/source/FilterKey.java +++ b/src/org/redkale/source/FilterKey.java @@ -6,6 +6,7 @@ package org.redkale.source; import java.util.Objects; +import org.redkale.util.ConstructorParameters; /** * FilterKey主要用于自身字段间的表达式, 如: a.recordid = a.parentid , a.parentid就需要FilterKey来表示 new FilterKey("parentid") @@ -21,7 +22,7 @@ public class FilterKey implements java.io.Serializable { private final String column; - @java.beans.ConstructorProperties({"column"}) + @ConstructorParameters({"column"}) public FilterKey(String column) { this.column = Objects.requireNonNull(column); } diff --git a/src/org/redkale/util/AnyValue.java b/src/org/redkale/util/AnyValue.java index 5220e5433..5bfd061aa 100644 --- a/src/org/redkale/util/AnyValue.java +++ b/src/org/redkale/util/AnyValue.java @@ -372,7 +372,7 @@ public abstract class AnyValue { T value; - @java.beans.ConstructorProperties({"name", "value"}) + @ConstructorParameters({"name", "value"}) public Entry(String name0, T value0) { this.name = name0; this.value = value0; diff --git a/src/org/redkale/util/ConstructorParameters.java b/src/org/redkale/util/ConstructorParameters.java new file mode 100644 index 000000000..ab456a138 --- /dev/null +++ b/src/org/redkale/util/ConstructorParameters.java @@ -0,0 +1,26 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package org.redkale.util; + +import java.lang.annotation.*; +import static java.lang.annotation.ElementType.*; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +/** + * 类似java.beans.ConstructorProperties, 必须配合Creator使用 + * + *

+ * 详情见: https://redkale.org + * + * @author zhangjx + */ +@Documented +@Target({METHOD, CONSTRUCTOR}) +@Retention(RUNTIME) +public @interface ConstructorParameters { + + String[] value(); +} diff --git a/src/org/redkale/util/Creator.java b/src/org/redkale/util/Creator.java index c55ba84b6..91b838c67 100644 --- a/src/org/redkale/util/Creator.java +++ b/src/org/redkale/util/Creator.java @@ -4,11 +4,7 @@ */ package org.redkale.util; -import java.beans.*; import java.io.*; -import java.lang.annotation.*; -import static java.lang.annotation.ElementType.*; -import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.reflect.*; import java.net.*; import java.util.*; @@ -56,7 +52,7 @@ import static org.redkale.asm.Opcodes.*; * * private String name; * - * @java.beans.ConstructorProperties({"id", "name"}) + * @ConstructorParameters({"id", "name"}) * public Record(int id, String name) { * this.id = id; * this.name = name; @@ -72,113 +68,101 @@ import static org.redkale.asm.Opcodes.*; */ public interface Creator { - /** - * 该注解只用于Creator.create方法上, 与 java.beans.ConstructorProperties 类似。 - * - */ - @Documented - @Target({METHOD}) - @Retention(RUNTIME) - public static @interface ConstructorParameters { + @SuppressWarnings("unchecked") + static class CreatorInner { - String[] value(); + static class SimpleClassVisitor extends ClassVisitor { - @SuppressWarnings("unchecked") - static class CreatorInner { + private final String constructorDesc; - static class SimpleClassVisitor extends ClassVisitor { + private final List fieldnames; - private final String constructorDesc; + private boolean started; - private final List fieldnames; + public SimpleClassVisitor(int api, List fieldnames, String constructorDesc) { + super(api); + this.fieldnames = fieldnames; + this.constructorDesc = constructorDesc; + } - private boolean started; - - public SimpleClassVisitor(int api, List fieldnames, String constructorDesc) { - super(api); - this.fieldnames = fieldnames; - this.constructorDesc = constructorDesc; - } - - @Override - public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { - if (java.lang.reflect.Modifier.isStatic(access) || !"".equals(name)) return null; - if (constructorDesc != null && !constructorDesc.equals(desc)) return null; - if (this.started) return null; - this.started = true; - //返回的List中参数列表可能会比方法参数量多,因为方法内的临时变量也会存入list中, 所以需要list的元素集合比方法的参数多 - return new MethodVisitor(Opcodes.ASM5) { - @Override - public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) { - if (index < 1) return; - int size = fieldnames.size(); - //index不会按顺序执行的 - if (index > size) { - for (int i = size; i < index; i++) { - fieldnames.add(" "); - } - fieldnames.set(index - 1, name); + @Override + public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) { + if (java.lang.reflect.Modifier.isStatic(access) || !"".equals(name)) return null; + if (constructorDesc != null && !constructorDesc.equals(desc)) return null; + if (this.started) return null; + this.started = true; + //返回的List中参数列表可能会比方法参数量多,因为方法内的临时变量也会存入list中, 所以需要list的元素集合比方法的参数多 + return new MethodVisitor(Opcodes.ASM5) { + @Override + public void visitLocalVariable(String name, String description, String signature, Label start, Label end, int index) { + if (index < 1) return; + int size = fieldnames.size(); + //index不会按顺序执行的 + if (index > size) { + for (int i = size; i < index; i++) { + fieldnames.add(" "); } fieldnames.set(index - 1, name); } - }; - } - } - - public static SimpleEntry[] getConstructorField(Class clazz, int paramcount, String constructorDesc) { - String n = clazz.getName(); - InputStream in = clazz.getResourceAsStream(n.substring(n.lastIndexOf('.') + 1) + ".class"); - if (in == null) return null; - ByteArrayOutputStream out = new ByteArrayOutputStream(1024); - byte[] bytes = new byte[1024]; - int pos; - try { - while ((pos = in.read(bytes)) != -1) { - out.write(bytes, 0, pos); + fieldnames.set(index - 1, name); } - in.close(); - } catch (IOException io) { + }; + } + } + + public static SimpleEntry[] getConstructorField(Class clazz, int paramcount, String constructorDesc) { + String n = clazz.getName(); + InputStream in = clazz.getResourceAsStream(n.substring(n.lastIndexOf('.') + 1) + ".class"); + if (in == null) return null; + ByteArrayOutputStream out = new ByteArrayOutputStream(1024); + byte[] bytes = new byte[1024]; + int pos; + try { + while ((pos = in.read(bytes)) != -1) { + out.write(bytes, 0, pos); + } + in.close(); + } catch (IOException io) { + return null; + } + final List fieldnames = new ArrayList<>(); + new ClassReader(out.toByteArray()).accept(new SimpleClassVisitor(Opcodes.ASM5, fieldnames, constructorDesc), 0); + if (fieldnames.isEmpty()) return null; + if (paramcount == fieldnames.size()) { + return getConstructorField(clazz, paramcount, fieldnames.toArray(new String[fieldnames.size()])); + } else { + String[] fs = new String[paramcount]; + for (int i = 0; i < fs.length; i++) { + fs[i] = fieldnames.get(i); + } + return getConstructorField(clazz, paramcount, fs); + } + } + + public static SimpleEntry[] getConstructorField(Class clazz, int paramcount, String[] names) { + SimpleEntry[] se = new SimpleEntry[names.length]; + for (int i = 0; i < names.length; i++) { //查询参数名对应的Field + try { + Field field = clazz.getDeclaredField(names[i]); + se[i] = new SimpleEntry<>(field.getName(), field.getType()); + } catch (Exception e) { return null; } - final List fieldnames = new ArrayList<>(); - new ClassReader(out.toByteArray()).accept(new SimpleClassVisitor(Opcodes.ASM5, fieldnames, constructorDesc), 0); - if (fieldnames.isEmpty()) return null; - if (paramcount == fieldnames.size()) { - return getConstructorField(clazz, paramcount, fieldnames.toArray(new String[fieldnames.size()])); - } else { - String[] fs = new String[paramcount]; - for (int i = 0; i < fs.length; i++) { - fs[i] = fieldnames.get(i); - } - return getConstructorField(clazz, paramcount, fs); - } } + return se; + } - public static SimpleEntry[] getConstructorField(Class clazz, int paramcount, String[] names) { - SimpleEntry[] se = new SimpleEntry[names.length]; - for (int i = 0; i < names.length; i++) { //查询参数名对应的Field - try { - Field field = clazz.getDeclaredField(names[i]); - se[i] = new SimpleEntry<>(field.getName(), field.getType()); - } catch (Exception e) { - return null; - } + public static SimpleEntry[] getConstructorField(Class clazz, int paramcount, Parameter[] params) { + SimpleEntry[] se = new SimpleEntry[params.length]; + for (int i = 0; i < params.length; i++) { //查询参数名对应的Field + try { + Field field = clazz.getDeclaredField(params[i].getName()); + se[i] = new SimpleEntry<>(field.getName(), field.getType()); + } catch (Exception e) { + return null; } - return se; - } - - public static SimpleEntry[] getConstructorField(Class clazz, int paramcount, Parameter[] params) { - SimpleEntry[] se = new SimpleEntry[params.length]; - for (int i = 0; i < params.length; i++) { //查询参数名对应的Field - try { - Field field = clazz.getDeclaredField(params[i].getName()); - se[i] = new SimpleEntry<>(field.getName(), field.getType()); - } catch (Exception e) { - return null; - } - } - return se; } + return se; } } @@ -252,9 +236,9 @@ public interface Creator { } if (constructor0 == null) { // 2、查找public带ConstructorProperties注解的构造函数 for (Constructor c : clazz.getConstructors()) { - ConstructorProperties cp = (ConstructorProperties) c.getAnnotation(ConstructorProperties.class); + ConstructorParameters cp = (ConstructorParameters) c.getAnnotation(ConstructorParameters.class); if (cp == null) continue; - SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value()); + SimpleEntry[] fields = CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value()); if (fields != null) { constructor0 = c; constructorParameters0 = fields; @@ -262,17 +246,17 @@ public interface Creator { } } } - if (constructor0 == null) { // 3、查找public且不带ConstructorProperties注解的构造函数 + if (constructor0 == null) { // 3、查找public且不带ConstructorParameters注解的构造函数 List cs = new ArrayList<>(); for (Constructor c : clazz.getConstructors()) { - if (c.getAnnotation(ConstructorProperties.class) != null) continue; + if (c.getAnnotation(ConstructorParameters.class) != null) continue; if (c.getParameterCount() < 1) continue; cs.add(c); } //优先参数最多的构造函数 cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount()); for (Constructor c : cs) { - SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, c.getParameterCount(), Type.getConstructorDescriptor(c)); + SimpleEntry[] fields = CreatorInner.getConstructorField(clazz, c.getParameterCount(), Type.getConstructorDescriptor(c)); if (fields != null) { constructor0 = c; constructorParameters0 = fields; @@ -283,9 +267,9 @@ public interface Creator { if (constructor0 == null) { // 4、查找非private带ConstructorProperties的构造函数 for (Constructor c : clazz.getDeclaredConstructors()) { if (Modifier.isPublic(c.getModifiers()) || Modifier.isPrivate(c.getModifiers())) continue; - ConstructorProperties cp = (ConstructorProperties) c.getAnnotation(ConstructorProperties.class); + ConstructorParameters cp = (ConstructorParameters) c.getAnnotation(ConstructorParameters.class); if (cp == null) continue; - SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value()); + SimpleEntry[] fields = CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value()); if (fields != null) { constructor0 = c; constructorParameters0 = fields; @@ -297,14 +281,14 @@ public interface Creator { List cs = new ArrayList<>(); for (Constructor c : clazz.getDeclaredConstructors()) { if (Modifier.isPublic(c.getModifiers()) || Modifier.isPrivate(c.getModifiers())) continue; - if (c.getAnnotation(ConstructorProperties.class) != null) continue; + if (c.getAnnotation(ConstructorParameters.class) != null) continue; if (c.getParameterCount() < 1) continue; cs.add(c); } //优先参数最多的构造函数 cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount()); for (Constructor c : cs) { - SimpleEntry[] fields = ConstructorParameters.CreatorInner.getConstructorField(clazz, c.getParameterCount(), Type.getConstructorDescriptor(c)); + SimpleEntry[] fields = CreatorInner.getConstructorField(clazz, c.getParameterCount(), Type.getConstructorDescriptor(c)); if (fields != null) { constructor0 = c; constructorParameters0 = fields; @@ -315,7 +299,7 @@ public interface Creator { final Constructor constructor = constructor0; final SimpleEntry[] constructorParameters = constructorParameters0; if (constructor == null || constructorParameters == null) { - throw new RuntimeException("[" + clazz + "] have no public or java.beans.ConstructorProperties-Annotation constructor."); + throw new RuntimeException("[" + clazz + "] have no public or ConstructorParameters-Annotation constructor."); } //------------------------------------------------------------- ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); @@ -475,7 +459,7 @@ public interface Creator { t.printStackTrace(); } } - if (!ispub && resultClazz == null) throw new RuntimeException("[" + clazz + "] have no public or java.beans.ConstructorProperties-Annotation constructor."); + if (!ispub && resultClazz == null) throw new RuntimeException("[" + clazz + "] have no public or ConstructorParameters-Annotation constructor."); try { if (resultClazz == null) resultClazz = new ClassLoader(loader) { public final Class loadClass(String name, byte[] b) { diff --git a/test/org/redkale/test/convert/ConstructorArgsEntity.java b/test/org/redkale/test/convert/ConstructorArgsEntity.java index 871b3a63a..77b86096c 100644 --- a/test/org/redkale/test/convert/ConstructorArgsEntity.java +++ b/test/org/redkale/test/convert/ConstructorArgsEntity.java @@ -5,9 +5,9 @@ */ package org.redkale.test.convert; -import java.beans.*; import org.redkale.convert.bson.*; import org.redkale.convert.json.*; +import org.redkale.util.ConstructorParameters; /** * 测试不存在无参数的构造函数的bean类解析 @@ -22,7 +22,7 @@ public class ConstructorArgsEntity { private long createtime; - @ConstructorProperties({"userid", "name"}) + @ConstructorParameters({"userid", "name"}) public ConstructorArgsEntity(int userid, String name) { this.userid = userid; this.name = name; diff --git a/test/org/redkale/test/util/CreatorRecord.java b/test/org/redkale/test/util/CreatorRecord.java index a9d4d41f4..3e1c76da5 100644 --- a/test/org/redkale/test/util/CreatorRecord.java +++ b/test/org/redkale/test/util/CreatorRecord.java @@ -5,7 +5,6 @@ */ package org.redkale.test.util; -import java.beans.*; import org.redkale.convert.json.*; import org.redkale.util.*; @@ -33,7 +32,7 @@ public class CreatorRecord { private double dval; - @ConstructorProperties({"id", "name", "lval", "tval", "bval", "sval", "cval", "fval", "dval"}) + @ConstructorParameters({"id", "name", "lval", "tval", "bval", "sval", "cval", "fval", "dval"}) CreatorRecord(int id, String name, long lval, boolean tval, byte bval, short sval, char cval, float fval, double dval) { this.id = id; this.name = name; diff --git a/test/org/redkale/test/util/ResourceTest.java b/test/org/redkale/test/util/ResourceTest.java index b35586607..8983d2b93 100644 --- a/test/org/redkale/test/util/ResourceTest.java +++ b/test/org/redkale/test/util/ResourceTest.java @@ -62,7 +62,7 @@ class BService { System.out.println("@Resource = " + name + " 资源变更: newVal = " + newVal + ", oldVal = " + oldVal); } - @java.beans.ConstructorProperties({"name"}) + @ConstructorParameters({"name"}) public BService(String name) { this.name = name; }