diff --git a/src/main/java/org/redkale/util/Creator.java b/src/main/java/org/redkale/util/Creator.java index 5c3be916c..1cb0e0f43 100644 --- a/src/main/java/org/redkale/util/Creator.java +++ b/src/main/java/org/redkale/util/Creator.java @@ -113,6 +113,15 @@ public interface Creator { return Inners.CreatorInner.creatorCacheMap.computeIfAbsent(clazz, v -> create(clazz)); } + public static Creator load(Class clazz, int paramCount) { + if (paramCount < 0) { + return Inners.CreatorInner.creatorCacheMap.computeIfAbsent(clazz, v -> create(clazz)); + } else { + return Inners.CreatorInner.creatorCacheMap2.computeIfAbsent( + clazz.getName() + "-" + paramCount, v -> create(clazz, paramCount)); + } + } + public static Creator register(Class clazz, final Supplier supplier) { Creator creator = (Object... params) -> supplier.get(); Inners.CreatorInner.creatorCacheMap.put(clazz, creator); @@ -200,6 +209,20 @@ public interface Creator { */ @SuppressWarnings("unchecked") public static Creator create(Class clazz) { + return create(clazz, -1); + } + + /** + * 根据指定的class采用ASM技术生产Creator。 + * + * @param 构建类的数据类型 + * @param clazz 构建类 + * @param paramCount 参数个数 + * @return Creator对象 + * @since 2.8.0 + */ + @SuppressWarnings("unchecked") + public static Creator create(Class clazz, int paramCount) { if (List.class.isAssignableFrom(clazz) && (clazz.isAssignableFrom(ArrayList.class) || clazz.getName().startsWith("java.util.Collections") @@ -237,9 +260,11 @@ public interface Creator { } else if (Future.class.isAssignableFrom(clazz) && clazz.isAssignableFrom(CompletableFuture.class)) { clazz = (Class) CompletableFuture.class; } - Creator creator = Inners.CreatorInner.creatorCacheMap.get(clazz); - if (creator != null) { - return creator; + if (paramCount < 0) { + Creator creator = Inners.CreatorInner.creatorCacheMap.get(clazz); + if (creator != null) { + return creator; + } } if (clazz.isInterface() || Modifier.isAbstract(clazz.getModifiers())) { throw new RedkaleException("[" + clazz + "] is a interface or abstract class, cannot create it's Creator."); @@ -274,7 +299,7 @@ public interface Creator { loader = clazz.getClassLoader(); } final String newDynName = "org/redkaledyn/creator/_Dyn" + Creator.class.getSimpleName() + "__" - + clazz.getName().replace('.', '_').replace('$', '_'); + + clazz.getName().replace('.', '_').replace('$', '_') + (paramCount < 0 ? "" : ("_" + paramCount)); try { Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); return (Creator) (clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz) @@ -289,7 +314,8 @@ public interface Creator { if (constructor0 == null) { // 1、查找public的空参数构造函数 for (Constructor c : clazz.getConstructors()) { - if (c.getParameterCount() == 0) { + int cc = c.getParameterCount(); + if (cc == 0 && (paramCount < 0 || cc == paramCount)) { constructor0 = c; constructorParameters0 = new SimpleEntry[0]; break; @@ -302,9 +328,9 @@ public interface Creator { if (cp == null) { continue; } - SimpleEntry[] fields = - Inners.CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value()); - if (fields != null) { + int cc = c.getParameterCount(); + SimpleEntry[] fields = Inners.CreatorInner.getConstructorField(clazz, cc, cp.value()); + if (fields != null && (paramCount < 0 || cc == paramCount)) { constructor0 = c; constructorParameters0 = fields; break; @@ -325,9 +351,10 @@ public interface Creator { // 优先参数最多的构造函数 cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount()); for (Constructor c : cs) { - SimpleEntry[] fields = Inners.CreatorInner.getConstructorField( - clazz, c.getParameterCount(), Type.getConstructorDescriptor(c)); - if (fields != null) { + int cc = c.getParameterCount(); + SimpleEntry[] fields = + Inners.CreatorInner.getConstructorField(clazz, cc, Type.getConstructorDescriptor(c)); + if (fields != null && (paramCount < 0 || cc == paramCount)) { constructor0 = c; constructorParameters0 = fields; break; @@ -343,9 +370,9 @@ public interface Creator { if (cp == null) { continue; } - SimpleEntry[] fields = - Inners.CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value()); - if (fields != null) { + int cc = c.getParameterCount(); + SimpleEntry[] fields = Inners.CreatorInner.getConstructorField(clazz, cc, cp.value()); + if (fields != null && (paramCount < 0 || cc == paramCount)) { constructor0 = c; constructorParameters0 = fields; break; @@ -369,9 +396,10 @@ public interface Creator { // 优先参数最多的构造函数 cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount()); for (Constructor c : cs) { - SimpleEntry[] fields = Inners.CreatorInner.getConstructorField( - clazz, c.getParameterCount(), Type.getConstructorDescriptor(c)); - if (fields != null) { + int cc = c.getParameterCount(); + SimpleEntry[] fields = + Inners.CreatorInner.getConstructorField(clazz, cc, Type.getConstructorDescriptor(c)); + if (fields != null && (paramCount < 0 || cc == paramCount)) { constructor0 = c; constructorParameters0 = fields; break; diff --git a/src/main/java/org/redkale/util/Inners.java b/src/main/java/org/redkale/util/Inners.java index 3feabb783..be93361f1 100644 --- a/src/main/java/org/redkale/util/Inners.java +++ b/src/main/java/org/redkale/util/Inners.java @@ -25,7 +25,9 @@ class Inners { static final Logger logger = Logger.getLogger(Creator.class.getSimpleName()); - static final Map creatorCacheMap = new HashMap<>(); + static final Map creatorCacheMap = new ConcurrentHashMap<>(); + + static final Map creatorCacheMap2 = new ConcurrentHashMap<>(); static final Map arrayCacheMap = new ConcurrentHashMap<>(); @@ -160,8 +162,9 @@ class Inners { final List fieldNames = new ArrayList<>(); new ClassReader(out.toByteArray()) .accept(new SimpleClassVisitor(Opcodes.ASM6, fieldNames, constructorDesc), 0); - while (fieldNames.remove(" ")) - ; // 删掉空元素 + while (fieldNames.remove(" ")) { + // 删掉空元素 + } if (fieldNames.isEmpty()) { return null; } diff --git a/src/test/java/org/redkale/test/sncp/SncpSleepTest.java b/src/test/java/org/redkale/test/sncp/SncpSleepTest.java index fda04693f..c07a2147f 100644 --- a/src/test/java/org/redkale/test/sncp/SncpSleepTest.java +++ b/src/test/java/org/redkale/test/sncp/SncpSleepTest.java @@ -1,6 +1,8 @@ package org.redkale.test.sncp; +import java.io.File; import java.net.InetSocketAddress; +import java.util.List; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import org.junit.jupiter.api.*; @@ -62,7 +64,7 @@ public class SncpSleepTest { CompletableFuture.allOf(futures).join(); long e = System.currentTimeMillis() - s; System.out.println("耗时: " + e + " ms"); - //remoteCService.test(333L, new String[] {"aaa", "bbb"}, List.of(new File("D:/a.txt"), new File("D:/b.txt"))); + remoteCService.test(333L, new String[] {"aaa", "bbb"}, List.of(new File("D:/a.txt"), new File("D:/b.txt"))); server.shutdown(); workExecutor.shutdown(); Assertions.assertTrue(e < 600); diff --git a/src/test/java/org/redkale/test/util/CreatorRecord.java b/src/test/java/org/redkale/test/util/CreatorRecord.java index 39b862280..40328eb2f 100644 --- a/src/test/java/org/redkale/test/util/CreatorRecord.java +++ b/src/test/java/org/redkale/test/util/CreatorRecord.java @@ -5,11 +5,8 @@ */ package org.redkale.test.util; -import java.util.Arrays; -import org.junit.jupiter.api.*; import org.redkale.annotation.ConstructorParameters; import org.redkale.convert.json.JsonConvert; -import org.redkale.util.Creator; /** @author zhangjx */ public class CreatorRecord { @@ -32,6 +29,8 @@ public class CreatorRecord { private double dval; + public CreatorRecord() {} + @ConstructorParameters({"id", "name", "lval", "tval", "bval", "sval", "cval", "fval", "dval"}) public CreatorRecord( int id, String name, long lval, boolean tval, byte bval, short sval, char cval, float fval, double dval) { @@ -46,17 +45,40 @@ public class CreatorRecord { this.dval = dval; } - @Test - public void run1() { - Creator creator = Creator.create(CreatorRecord.class); - System.out.println(Arrays.toString(creator.paramTypes())); - CreatorRecord record = - creator.create(new Object[] {null, "ss", null, true, null, (short) 45, null, 4.3f, null}); - String json = record.toString(); - System.out.println(json); - String json2 = JsonConvert.root().convertFrom(CreatorRecord.class, json).toString(); - System.out.println(json2); - Assertions.assertEquals(json, json2); + public void setId(int id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public void setLval(long lval) { + this.lval = lval; + } + + public void setTval(boolean tval) { + this.tval = tval; + } + + public void setBval(byte bval) { + this.bval = bval; + } + + public void setSval(short sval) { + this.sval = sval; + } + + public void setCval(char cval) { + this.cval = cval; + } + + public void setFval(float fval) { + this.fval = fval; + } + + public void setDval(double dval) { + this.dval = dval; } @Override diff --git a/src/test/java/org/redkale/test/util/CreatorTest.java b/src/test/java/org/redkale/test/util/CreatorTest.java new file mode 100644 index 000000000..60b90f7c7 --- /dev/null +++ b/src/test/java/org/redkale/test/util/CreatorTest.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016-2116 Redkale + * All rights reserved. + */ +package org.redkale.test.util; + +import java.util.Arrays; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; +import org.redkale.convert.json.JsonConvert; +import org.redkale.util.Creator; + +/** + * + * @author zhangjx + */ +public class CreatorTest { + + public static void main(String[] args) throws Throwable { + CreatorTest test = new CreatorTest(); + test.run1(); + } + + @Test + public void run1() throws Throwable { + Creator creator = Creator.create(CreatorRecord.class, 9); + Creator.load(CreatorRecord.class); + System.out.println(Arrays.toString(creator.paramTypes())); + CreatorRecord record = + creator.create(new Object[] {null, "ss", null, true, null, (short) 45, null, 4.3f, null}); + String json = record.toString(); + System.out.println(json); + String json2 = JsonConvert.root().convertFrom(CreatorRecord.class, json).toString(); + System.out.println(json2); + Assertions.assertEquals("ss", record.getName()); + Assertions.assertEquals(json, json2); + } +}