This commit is contained in:
redkale
2024-10-10 22:29:39 +08:00
parent ed2d9527bf
commit 8ea63c5171
5 changed files with 128 additions and 35 deletions

View File

@@ -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;

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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

View 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);
}
}