From 1a95fb3d3ac6f5e418670b70a7f698d4050a22ed Mon Sep 17 00:00:00 2001 From: redkale Date: Tue, 22 Aug 2023 23:07:18 +0800 Subject: [PATCH] Inners --- .../org/redkale/convert/json/JsonConvert.java | 2 +- src/main/java/org/redkale/util/Copier.java | 36 +-- src/main/java/org/redkale/util/Creator.java | 270 +--------------- src/main/java/org/redkale/util/Inners.java | 304 ++++++++++++++++++ src/main/java/org/redkale/util/Invoker.java | 7 +- 5 files changed, 321 insertions(+), 298 deletions(-) create mode 100644 src/main/java/org/redkale/util/Inners.java diff --git a/src/main/java/org/redkale/convert/json/JsonConvert.java b/src/main/java/org/redkale/convert/json/JsonConvert.java index 2bb98c88e..497b9c79d 100644 --- a/src/main/java/org/redkale/convert/json/JsonConvert.java +++ b/src/main/java/org/redkale/convert/json/JsonConvert.java @@ -25,7 +25,7 @@ import org.redkale.util.*; @SuppressWarnings("unchecked") public class JsonConvert extends TextConvert { - public static final Type TYPE_MAP_STRING_STRING = new TypeToken>() { + public static final Type TYPE_MAP_STRING_STRING = new TypeToken>() { }.getType(); public static final Type TYPE_LIST_STRING = new TypeToken>() { diff --git a/src/main/java/org/redkale/util/Copier.java b/src/main/java/org/redkale/util/Copier.java index 47c4a34d5..e7f87e047 100644 --- a/src/main/java/org/redkale/util/Copier.java +++ b/src/main/java/org/redkale/util/Copier.java @@ -251,7 +251,7 @@ public interface Copier extends BiFunction { public static Function, Collection> funcCollection(final Class srcClass, final Class destClass, final int options, final Class collectionClass) { if (destClass == srcClass) { - return CopierInner.funcListOneCaches + return Inners.CopierInner.copierFuncListOneCaches .computeIfAbsent(collectionClass, t -> new ConcurrentHashMap<>()) .computeIfAbsent(options, t -> new ConcurrentHashMap<>()) .computeIfAbsent(srcClass, v -> { @@ -273,7 +273,7 @@ public interface Copier extends BiFunction { return funcList; }); } else { - return CopierInner.funcListTwoCaches + return Inners.CopierInner.copierFuncListTwoCaches .computeIfAbsent(collectionClass, t -> new ConcurrentHashMap<>()) .computeIfAbsent(options, t -> new ConcurrentHashMap<>()) .computeIfAbsent(srcClass, t -> new ConcurrentHashMap<>()) @@ -311,7 +311,7 @@ public interface Copier extends BiFunction { */ public static Function func(final Class srcClass, final Class destClass, final int options) { if (destClass == srcClass) { - return CopierInner.funcOneCaches + return Inners.CopierInner.copierFuncOneCaches .computeIfAbsent(options, t -> new ConcurrentHashMap<>()) .computeIfAbsent(srcClass, v -> { Copier copier = load(srcClass, destClass, options); @@ -320,7 +320,7 @@ public interface Copier extends BiFunction { return func; }); } else { - return CopierInner.funcTwoCaches + return Inners.CopierInner.copierFuncTwoCaches .computeIfAbsent(options, t -> new ConcurrentHashMap<>()) .computeIfAbsent(srcClass, t -> new ConcurrentHashMap<>()) .computeIfAbsent(destClass, v -> { @@ -345,11 +345,11 @@ public interface Copier extends BiFunction { */ public static Copier load(final Class srcClass, final Class destClass, final int options) { if (destClass == srcClass) { - return CopierInner.copierOneCaches + return Inners.CopierInner.copierOneCaches .computeIfAbsent(options, t -> new ConcurrentHashMap<>()) .computeIfAbsent(srcClass, v -> create(srcClass, destClass, options)); } else { - return CopierInner.copierTwoCaches + return Inners.CopierInner.copierTwoCaches .computeIfAbsent(options, t -> new ConcurrentHashMap<>()) .computeIfAbsent(srcClass, t -> new ConcurrentHashMap<>()) .computeIfAbsent(destClass, v -> create(srcClass, destClass, options)); @@ -1124,28 +1124,4 @@ public interface Copier extends BiFunction { } } - static class CopierInner { - - static final ConcurrentHashMap> copierOneCaches = new ConcurrentHashMap(); - - static final ConcurrentHashMap>> copierTwoCaches = new ConcurrentHashMap(); - - static final ConcurrentHashMap> funcOneCaches = new ConcurrentHashMap(); - - static final ConcurrentHashMap>> funcTwoCaches = new ConcurrentHashMap(); - - static final ConcurrentHashMap>> funcListOneCaches = new ConcurrentHashMap(); - - static final ConcurrentHashMap>>> funcListTwoCaches = new ConcurrentHashMap(); - - public static void clear() { - copierOneCaches.clear(); - copierTwoCaches.clear(); - funcOneCaches.clear(); - funcTwoCaches.clear(); - funcListOneCaches.clear(); - funcListTwoCaches.clear(); - } - } - } diff --git a/src/main/java/org/redkale/util/Creator.java b/src/main/java/org/redkale/util/Creator.java index 12a684f0c..743b2d74b 100644 --- a/src/main/java/org/redkale/util/Creator.java +++ b/src/main/java/org/redkale/util/Creator.java @@ -6,15 +6,11 @@ package org.redkale.util; import java.io.*; import java.lang.reflect.*; -import java.math.*; import java.net.*; -import java.nio.ByteBuffer; import java.util.AbstractMap.SimpleEntry; import java.util.*; import java.util.concurrent.*; import java.util.function.*; -import java.util.logging.*; -import java.util.stream.Stream; import org.redkale.annotation.ConstructorParameters; import org.redkale.asm.*; import static org.redkale.asm.Opcodes.*; @@ -102,22 +98,22 @@ public interface Creator { * @return IntFunction */ public static IntFunction funcArray(final Class type) { - return CreatorInner.arrayCacheMap.computeIfAbsent(type, CreatorInner::createArrayFunction); + return Inners.CreatorInner.arrayCacheMap.computeIfAbsent(type, Inners.CreatorInner::createArrayFunction); } public static Creator load(Class clazz) { - return CreatorInner.creatorCacheMap.computeIfAbsent(clazz, v -> create(clazz)); + return Inners.CreatorInner.creatorCacheMap.computeIfAbsent(clazz, v -> create(clazz)); } public static Creator register(Class clazz, final Supplier supplier) { Creator creator = (Object... params) -> supplier.get(); - CreatorInner.creatorCacheMap.put(clazz, creator); + Inners.CreatorInner.creatorCacheMap.put(clazz, creator); return creator; } public static Creator register(final LambdaSupplier supplier) { Creator creator = (Object... params) -> supplier.get(); - CreatorInner.creatorCacheMap.put(LambdaSupplier.readClass(supplier), creator); + Inners.CreatorInner.creatorCacheMap.put(LambdaSupplier.readClass(supplier), creator); return creator; } @@ -231,7 +227,7 @@ public interface Creator { } else if (Future.class.isAssignableFrom(clazz) && clazz.isAssignableFrom(CompletableFuture.class)) { clazz = (Class) CompletableFuture.class; } - Creator creator = CreatorInner.creatorCacheMap.get(clazz); + Creator creator = Inners.CreatorInner.creatorCacheMap.get(clazz); if (creator != null) { return creator; } @@ -292,7 +288,7 @@ public interface Creator { if (cp == null) { continue; } - SimpleEntry[] fields = CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value()); + SimpleEntry[] fields = Inners.CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value()); if (fields != null) { constructor0 = c; constructorParameters0 = fields; @@ -314,7 +310,7 @@ public interface Creator { //优先参数最多的构造函数 cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount()); for (Constructor c : cs) { - SimpleEntry[] fields = CreatorInner.getConstructorField(clazz, c.getParameterCount(), Type.getConstructorDescriptor(c)); + SimpleEntry[] fields = Inners.CreatorInner.getConstructorField(clazz, c.getParameterCount(), Type.getConstructorDescriptor(c)); if (fields != null) { constructor0 = c; constructorParameters0 = fields; @@ -331,7 +327,7 @@ public interface Creator { if (cp == null) { continue; } - SimpleEntry[] fields = CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value()); + SimpleEntry[] fields = Inners.CreatorInner.getConstructorField(clazz, c.getParameterCount(), cp.value()); if (fields != null) { constructor0 = c; constructorParameters0 = fields; @@ -356,7 +352,7 @@ public interface Creator { //优先参数最多的构造函数 cs.sort((o1, o2) -> o2.getParameterCount() - o1.getParameterCount()); for (Constructor c : cs) { - SimpleEntry[] fields = CreatorInner.getConstructorField(clazz, c.getParameterCount(), Type.getConstructorDescriptor(c)); + SimpleEntry[] fields = Inners.CreatorInner.getConstructorField(clazz, c.getParameterCount(), Type.getConstructorDescriptor(c)); if (fields != null) { constructor0 = c; constructorParameters0 = fields; @@ -581,252 +577,4 @@ public interface Creator { } } - @SuppressWarnings("unchecked") - static class CreatorInner { - - static final Logger logger = Logger.getLogger(Creator.class.getSimpleName()); - - static final Map creatorCacheMap = new HashMap<>(); - - static final Map arrayCacheMap = new ConcurrentHashMap<>(); - - static { - creatorCacheMap.put(Object.class, p -> new Object()); - creatorCacheMap.put(ArrayList.class, p -> new ArrayList<>()); - creatorCacheMap.put(HashMap.class, p -> new HashMap<>()); - creatorCacheMap.put(HashSet.class, p -> new HashSet<>()); - creatorCacheMap.put(LinkedHashSet.class, p -> new LinkedHashSet<>()); - creatorCacheMap.put(Stream.class, p -> new ArrayList<>().stream()); - creatorCacheMap.put(ConcurrentHashMap.class, p -> new ConcurrentHashMap<>()); - creatorCacheMap.put(CompletableFuture.class, p -> new CompletableFuture<>()); - creatorCacheMap.put(CompletionStage.class, p -> new CompletableFuture<>()); - creatorCacheMap.put(Future.class, p -> new CompletableFuture<>()); - creatorCacheMap.put(AnyValue.DefaultAnyValue.class, p -> new AnyValue.DefaultAnyValue()); - creatorCacheMap.put(AnyValue.class, p -> new AnyValue.DefaultAnyValue()); - creatorCacheMap.put(Map.Entry.class, new Creator() { - @Override - @ConstructorParameters({"key", "value"}) - public Map.Entry create(Object... params) { - return new AbstractMap.SimpleEntry(params[0], params[1]); - } - - @Override - public Class[] paramTypes() { - return new Class[]{Object.class, Object.class}; - } - }); - creatorCacheMap.put(AbstractMap.SimpleEntry.class, new Creator() { - @Override - @ConstructorParameters({"key", "value"}) - public AbstractMap.SimpleEntry create(Object... params) { - return new AbstractMap.SimpleEntry(params[0], params[1]); - } - - @Override - public Class[] paramTypes() { - return new Class[]{Object.class, Object.class}; - } - }); - - arrayCacheMap.put(int.class, t -> new int[t]); - arrayCacheMap.put(byte.class, t -> new byte[t]); - arrayCacheMap.put(long.class, t -> new long[t]); - arrayCacheMap.put(String.class, t -> new String[t]); - arrayCacheMap.put(Object.class, t -> new Object[t]); - arrayCacheMap.put(boolean.class, t -> new boolean[t]); - arrayCacheMap.put(short.class, t -> new short[t]); - arrayCacheMap.put(char.class, t -> new char[t]); - arrayCacheMap.put(float.class, t -> new float[t]); - arrayCacheMap.put(double.class, t -> new double[t]); - arrayCacheMap.put(BigInteger.class, t -> new BigInteger[t]); - arrayCacheMap.put(BigDecimal.class, t -> new BigDecimal[t]); - arrayCacheMap.put(ByteBuffer.class, t -> new ByteBuffer[t]); - arrayCacheMap.put(SocketAddress.class, t -> new SocketAddress[t]); - arrayCacheMap.put(InetSocketAddress.class, t -> new InetSocketAddress[t]); - arrayCacheMap.put(CompletableFuture.class, t -> new CompletableFuture[t]); - } - - static class SimpleClassVisitor extends ClassVisitor { - - private final String constructorDesc; - - private final List fieldNames; - - 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.ASM6) { - @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); - } - 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); - } - in.close(); - } catch (IOException io) { - return null; - } - final List fieldNames = new ArrayList<>(); - new ClassReader(out.toByteArray()).accept(new SimpleClassVisitor(Opcodes.ASM6, fieldNames, constructorDesc), 0); - while (fieldNames.remove(" ")); //删掉空元素 - 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 (NoSuchFieldException fe) { - Class cz = clazz; - Field field = null; - while ((cz = cz.getSuperclass()) != Object.class) { - try { - field = cz.getDeclaredField(names[i]); - break; - } catch (NoSuchFieldException nsfe) { - } - } - if (field == null) { - return null; - } - se[i] = new SimpleEntry<>(field.getName(), field.getType()); - } catch (Exception e) { - if (logger.isLoggable(Level.FINE)) { - logger.log(Level.FINE, clazz + " getConstructorField error", 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; - } - - public static IntFunction createArrayFunction(final Class clazz) { - final String interName = clazz.getName().replace('.', '/'); - final String interDesc = Type.getDescriptor(clazz); - final ClassLoader loader = clazz.getClassLoader(); - final String newDynName = "org/redkaledyn/creator/_DynArrayFunction__" + clazz.getName().replace('.', '_').replace('$', '_'); - try { - Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); - return (IntFunction) (clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz).getDeclaredConstructor().newInstance(); - } catch (Throwable ex) { - } - - //------------------------------------------------------------- - ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); - MethodVisitor mv; - cw.visit(V11, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, "Ljava/lang/Object;Ljava/util/function/IntFunction<[" + interDesc + ">;", "java/lang/Object", new String[]{"java/util/function/IntFunction"}); - - {//IntFunction自身的构造方法 - mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); - mv.visitVarInsn(ALOAD, 0); - mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); - mv.visitInsn(RETURN); - mv.visitMaxs(1, 1); - mv.visitEnd(); - } - {//apply 方法 - mv = cw.visitMethod(ACC_PUBLIC, "apply", "(I)[" + interDesc, null, null); - mv.visitVarInsn(ILOAD, 1); - mv.visitTypeInsn(ANEWARRAY, interName); - mv.visitInsn(ARETURN); - mv.visitMaxs(1, 2); - mv.visitEnd(); - } - { //虚拟 apply 方法 - mv = cw.visitMethod(ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "apply", "(I)Ljava/lang/Object;", null, null); - mv.visitVarInsn(ALOAD, 0); - mv.visitVarInsn(ILOAD, 1); - mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "apply", "(I)[" + interDesc, false); - mv.visitInsn(ARETURN); - mv.visitMaxs(2, 2); - mv.visitEnd(); - } - cw.visitEnd(); - final byte[] bytes = cw.toByteArray(); - try { - Class resultClazz = new ClassLoader(loader) { - public final Class loadClass(String name, byte[] b) { - return defineClass(name, b, 0, b.length); - } - }.loadClass(newDynName.replace('/', '.'), bytes); - RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, resultClazz); - RedkaleClassLoader.putReflectionDeclaredConstructors(resultClazz, newDynName.replace('/', '.')); - return (IntFunction) resultClazz.getDeclaredConstructor().newInstance(); - } catch (Throwable ex) { - //ex.printStackTrace(); //一般不会发生, native-image在没有预编译情况下会报错 - return t -> (T[]) Array.newInstance(clazz, t); - } - } - } - } diff --git a/src/main/java/org/redkale/util/Inners.java b/src/main/java/org/redkale/util/Inners.java new file mode 100644 index 000000000..5deda735a --- /dev/null +++ b/src/main/java/org/redkale/util/Inners.java @@ -0,0 +1,304 @@ +/* + * + */ +package org.redkale.util; + +import java.io.*; +import java.lang.reflect.*; +import java.math.*; +import java.net.*; +import java.nio.ByteBuffer; +import java.util.*; +import java.util.concurrent.*; +import java.util.function.*; +import java.util.logging.*; +import java.util.stream.Stream; +import org.redkale.asm.*; +import static org.redkale.asm.Opcodes.*; + +/** + * + * @author zhangjx + */ +class Inners { + + private Inners() { + } + + static class CreatorInner { + + static final Logger logger = Logger.getLogger(Creator.class.getSimpleName()); + + static final Map creatorCacheMap = new HashMap<>(); + + static final Map arrayCacheMap = new ConcurrentHashMap<>(); + + static { + creatorCacheMap.put(Object.class, p -> new Object()); + creatorCacheMap.put(ArrayList.class, p -> new ArrayList<>()); + creatorCacheMap.put(HashMap.class, p -> new HashMap<>()); + creatorCacheMap.put(HashSet.class, p -> new HashSet<>()); + creatorCacheMap.put(LinkedHashSet.class, p -> new LinkedHashSet<>()); + creatorCacheMap.put(Stream.class, p -> new ArrayList<>().stream()); + creatorCacheMap.put(ConcurrentHashMap.class, p -> new ConcurrentHashMap<>()); + creatorCacheMap.put(CompletableFuture.class, p -> new CompletableFuture<>()); + creatorCacheMap.put(CompletionStage.class, p -> new CompletableFuture<>()); + creatorCacheMap.put(Future.class, p -> new CompletableFuture<>()); + creatorCacheMap.put(AnyValue.DefaultAnyValue.class, p -> new AnyValue.DefaultAnyValue()); + creatorCacheMap.put(AnyValue.class, p -> new AnyValue.DefaultAnyValue()); + creatorCacheMap.put(Map.Entry.class, new Creator() { + @Override + @org.redkale.annotation.ConstructorParameters({"key", "value"}) + public Map.Entry create(Object... params) { + return new AbstractMap.SimpleEntry(params[0], params[1]); + } + + @Override + public Class[] paramTypes() { + return new Class[]{Object.class, Object.class}; + } + }); + creatorCacheMap.put(AbstractMap.SimpleEntry.class, new Creator() { + @Override + @org.redkale.annotation.ConstructorParameters({"key", "value"}) + public AbstractMap.SimpleEntry create(Object... params) { + return new AbstractMap.SimpleEntry(params[0], params[1]); + } + + @Override + public Class[] paramTypes() { + return new Class[]{Object.class, Object.class}; + } + }); + + arrayCacheMap.put(int.class, t -> new int[t]); + arrayCacheMap.put(byte.class, t -> new byte[t]); + arrayCacheMap.put(long.class, t -> new long[t]); + arrayCacheMap.put(String.class, t -> new String[t]); + arrayCacheMap.put(Object.class, t -> new Object[t]); + arrayCacheMap.put(boolean.class, t -> new boolean[t]); + arrayCacheMap.put(short.class, t -> new short[t]); + arrayCacheMap.put(char.class, t -> new char[t]); + arrayCacheMap.put(float.class, t -> new float[t]); + arrayCacheMap.put(double.class, t -> new double[t]); + arrayCacheMap.put(BigInteger.class, t -> new BigInteger[t]); + arrayCacheMap.put(BigDecimal.class, t -> new BigDecimal[t]); + arrayCacheMap.put(ByteBuffer.class, t -> new ByteBuffer[t]); + arrayCacheMap.put(SocketAddress.class, t -> new SocketAddress[t]); + arrayCacheMap.put(InetSocketAddress.class, t -> new InetSocketAddress[t]); + arrayCacheMap.put(CompletableFuture.class, t -> new CompletableFuture[t]); + } + + static class SimpleClassVisitor extends ClassVisitor { + + private final String constructorDesc; + + private final List fieldNames; + + 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.ASM6) { + @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); + } + fieldNames.set(index - 1, name); + } + }; + } + } + + public static AbstractMap.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.ASM6, fieldNames, constructorDesc), 0); + while (fieldNames.remove(" ")); //删掉空元素 + 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 AbstractMap.SimpleEntry[] getConstructorField(Class clazz, int paramCount, String[] names) { + AbstractMap.SimpleEntry[] se = new AbstractMap.SimpleEntry[names.length]; + for (int i = 0; i < names.length; i++) { //查询参数名对应的Field + try { + Field field = clazz.getDeclaredField(names[i]); + se[i] = new AbstractMap.SimpleEntry<>(field.getName(), field.getType()); + } catch (NoSuchFieldException fe) { + Class cz = clazz; + Field field = null; + while ((cz = cz.getSuperclass()) != Object.class) { + try { + field = cz.getDeclaredField(names[i]); + break; + } catch (NoSuchFieldException nsfe) { + } + } + if (field == null) { + return null; + } + se[i] = new AbstractMap.SimpleEntry<>(field.getName(), field.getType()); + } catch (Exception e) { + if (logger.isLoggable(Level.FINE)) { + logger.log(Level.FINE, clazz + " getConstructorField error", e); + } + return null; + } + } + return se; + } + + public static AbstractMap.SimpleEntry[] getConstructorField(Class clazz, int paramCount, Parameter[] params) { + AbstractMap.SimpleEntry[] se = new AbstractMap.SimpleEntry[params.length]; + for (int i = 0; i < params.length; i++) { //查询参数名对应的Field + try { + Field field = clazz.getDeclaredField(params[i].getName()); + se[i] = new AbstractMap.SimpleEntry<>(field.getName(), field.getType()); + } catch (Exception e) { + return null; + } + } + return se; + } + + public static IntFunction createArrayFunction(final Class clazz) { + final String interName = clazz.getName().replace('.', '/'); + final String interDesc = org.redkale.asm.Type.getDescriptor(clazz); + final ClassLoader loader = clazz.getClassLoader(); + final String newDynName = "org/redkaledyn/creator/_DynArrayFunction__" + clazz.getName().replace('.', '_').replace('$', '_'); + try { + Class clz = RedkaleClassLoader.findDynClass(newDynName.replace('/', '.')); + return (IntFunction) (clz == null ? loader.loadClass(newDynName.replace('/', '.')) : clz).getDeclaredConstructor().newInstance(); + } catch (Throwable ex) { + } + + //------------------------------------------------------------- + ClassWriter cw = new ClassWriter(ClassWriter.COMPUTE_FRAMES); + MethodVisitor mv; + cw.visit(V11, ACC_PUBLIC + ACC_FINAL + ACC_SUPER, newDynName, "Ljava/lang/Object;Ljava/util/function/IntFunction<[" + interDesc + ">;", "java/lang/Object", new String[]{"java/util/function/IntFunction"}); + + {//IntFunction自身的构造方法 + mv = cw.visitMethod(ACC_PUBLIC, "", "()V", null, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()V", false); + mv.visitInsn(RETURN); + mv.visitMaxs(1, 1); + mv.visitEnd(); + } + {//apply 方法 + mv = cw.visitMethod(ACC_PUBLIC, "apply", "(I)[" + interDesc, null, null); + mv.visitVarInsn(ILOAD, 1); + mv.visitTypeInsn(ANEWARRAY, interName); + mv.visitInsn(ARETURN); + mv.visitMaxs(1, 2); + mv.visitEnd(); + } + { //虚拟 apply 方法 + mv = cw.visitMethod(ACC_PUBLIC + ACC_BRIDGE + ACC_SYNTHETIC, "apply", "(I)Ljava/lang/Object;", null, null); + mv.visitVarInsn(ALOAD, 0); + mv.visitVarInsn(ILOAD, 1); + mv.visitMethodInsn(INVOKEVIRTUAL, newDynName, "apply", "(I)[" + interDesc, false); + mv.visitInsn(ARETURN); + mv.visitMaxs(2, 2); + mv.visitEnd(); + } + cw.visitEnd(); + final byte[] bytes = cw.toByteArray(); + try { + Class resultClazz = new ClassLoader(loader) { + public final Class loadClass(String name, byte[] b) { + return defineClass(name, b, 0, b.length); + } + }.loadClass(newDynName.replace('/', '.'), bytes); + RedkaleClassLoader.putDynClass(newDynName.replace('/', '.'), bytes, resultClazz); + RedkaleClassLoader.putReflectionDeclaredConstructors(resultClazz, newDynName.replace('/', '.')); + return (IntFunction) resultClazz.getDeclaredConstructor().newInstance(); + } catch (Throwable ex) { + //ex.printStackTrace(); //一般不会发生, native-image在没有预编译情况下会报错 + return t -> (T[]) Array.newInstance(clazz, t); + } + } + } + + static class CopierInner { + + static final ConcurrentHashMap> copierOneCaches = new ConcurrentHashMap(); + + static final ConcurrentHashMap>> copierTwoCaches = new ConcurrentHashMap(); + + static final ConcurrentHashMap> copierFuncOneCaches = new ConcurrentHashMap(); + + static final ConcurrentHashMap>> copierFuncTwoCaches = new ConcurrentHashMap(); + + static final ConcurrentHashMap>> copierFuncListOneCaches = new ConcurrentHashMap(); + + static final ConcurrentHashMap>>> copierFuncListTwoCaches = new ConcurrentHashMap(); + + public static void clearCopierCache() { + copierOneCaches.clear(); + copierTwoCaches.clear(); + copierFuncOneCaches.clear(); + copierFuncTwoCaches.clear(); + copierFuncListOneCaches.clear(); + copierFuncListTwoCaches.clear(); + } + } + + static class InvokerInner { + + static final ConcurrentHashMap> invokerCaches = new ConcurrentHashMap(); + + } +} diff --git a/src/main/java/org/redkale/util/Invoker.java b/src/main/java/org/redkale/util/Invoker.java index e618f7cac..ce23bb170 100644 --- a/src/main/java/org/redkale/util/Invoker.java +++ b/src/main/java/org/redkale/util/Invoker.java @@ -56,7 +56,7 @@ public interface Invoker { } public static Invoker load(final Class clazz, final Method method) { - return InvokerInner.caches + return Inners.InvokerInner.invokerCaches .computeIfAbsent(clazz, t -> new ConcurrentHashMap<>()) .computeIfAbsent(method, v -> create(clazz, method)); } @@ -190,9 +190,4 @@ public interface Invoker { } } - static class InvokerInner { - - static final ConcurrentHashMap> caches = new ConcurrentHashMap(); - - } }