creator
This commit is contained in:
@@ -113,6 +113,15 @@ public interface Creator<T> {
|
||||
return Inners.CreatorInner.creatorCacheMap.computeIfAbsent(clazz, v -> create(clazz));
|
||||
}
|
||||
|
||||
public static <T> Creator<T> load(Class<T> 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 <T> Creator<T> register(Class<T> clazz, final Supplier<T> supplier) {
|
||||
Creator<T> creator = (Object... params) -> supplier.get();
|
||||
Inners.CreatorInner.creatorCacheMap.put(clazz, creator);
|
||||
@@ -200,6 +209,20 @@ public interface Creator<T> {
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Creator<T> create(Class<T> clazz) {
|
||||
return create(clazz, -1);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据指定的class采用ASM技术生产Creator。
|
||||
*
|
||||
* @param <T> 构建类的数据类型
|
||||
* @param clazz 构建类
|
||||
* @param paramCount 参数个数
|
||||
* @return Creator对象
|
||||
* @since 2.8.0
|
||||
*/
|
||||
@SuppressWarnings("unchecked")
|
||||
public static <T> Creator<T> create(Class<T> 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<T> {
|
||||
} else if (Future.class.isAssignableFrom(clazz) && clazz.isAssignableFrom(CompletableFuture.class)) {
|
||||
clazz = (Class<T>) 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<T> {
|
||||
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<T> {
|
||||
|
||||
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<T> {
|
||||
if (cp == null) {
|
||||
continue;
|
||||
}
|
||||
SimpleEntry<String, Class>[] fields =
|
||||
Inners.CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value());
|
||||
if (fields != null) {
|
||||
int cc = c.getParameterCount();
|
||||
SimpleEntry<String, Class>[] 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<T> {
|
||||
// 优先参数最多的构造函数
|
||||
cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount());
|
||||
for (Constructor c : cs) {
|
||||
SimpleEntry<String, Class>[] fields = Inners.CreatorInner.getConstructorField(
|
||||
clazz, c.getParameterCount(), Type.getConstructorDescriptor(c));
|
||||
if (fields != null) {
|
||||
int cc = c.getParameterCount();
|
||||
SimpleEntry<String, Class>[] 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<T> {
|
||||
if (cp == null) {
|
||||
continue;
|
||||
}
|
||||
SimpleEntry<String, Class>[] fields =
|
||||
Inners.CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value());
|
||||
if (fields != null) {
|
||||
int cc = c.getParameterCount();
|
||||
SimpleEntry<String, Class>[] 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<T> {
|
||||
// 优先参数最多的构造函数
|
||||
cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount());
|
||||
for (Constructor c : cs) {
|
||||
SimpleEntry<String, Class>[] fields = Inners.CreatorInner.getConstructorField(
|
||||
clazz, c.getParameterCount(), Type.getConstructorDescriptor(c));
|
||||
if (fields != null) {
|
||||
int cc = c.getParameterCount();
|
||||
SimpleEntry<String, Class>[] fields =
|
||||
Inners.CreatorInner.getConstructorField(clazz, cc, Type.getConstructorDescriptor(c));
|
||||
if (fields != null && (paramCount < 0 || cc == paramCount)) {
|
||||
constructor0 = c;
|
||||
constructorParameters0 = fields;
|
||||
break;
|
||||
|
||||
@@ -25,7 +25,9 @@ class Inners {
|
||||
|
||||
static final Logger logger = Logger.getLogger(Creator.class.getSimpleName());
|
||||
|
||||
static final Map<Class, Creator> creatorCacheMap = new HashMap<>();
|
||||
static final Map<Class, Creator> creatorCacheMap = new ConcurrentHashMap<>();
|
||||
|
||||
static final Map<String, Creator> creatorCacheMap2 = new ConcurrentHashMap<>();
|
||||
|
||||
static final Map<Class, IntFunction> arrayCacheMap = new ConcurrentHashMap<>();
|
||||
|
||||
@@ -160,8 +162,9 @@ class Inners {
|
||||
final List<String> 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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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<CreatorRecord> 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
|
||||
|
||||
38
src/test/java/org/redkale/test/util/CreatorTest.java
Normal file
38
src/test/java/org/redkale/test/util/CreatorTest.java
Normal file
@@ -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<CreatorRecord> 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);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user