diff --git a/core/src/main/java/org/jdbi/v3/core/mapper/reflect/ConstructorInstanceFactory.java b/core/src/main/java/org/jdbi/v3/core/mapper/reflect/ConstructorInstanceFactory.java index 06c8c3411..ffab479c4 100644 --- a/core/src/main/java/org/jdbi/v3/core/mapper/reflect/ConstructorInstanceFactory.java +++ b/core/src/main/java/org/jdbi/v3/core/mapper/reflect/ConstructorInstanceFactory.java @@ -19,6 +19,8 @@ import java.lang.reflect.Parameter; import java.lang.reflect.Type; import java.util.Arrays; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; import java.util.stream.Stream; @@ -27,19 +29,18 @@ import static java.util.Objects.requireNonNull; class ConstructorInstanceFactory extends InstanceFactory { - private final Constructor constructor; + private static final Map CONSTRUCTOR_CACHE = new ConcurrentHashMap<>(); - private final Supplier typeSupplier; + private final Constructor constructor; ConstructorInstanceFactory(Constructor constructor) { super(constructor); this.constructor = requireNonNull(constructor, "constructor is null"); - this.typeSupplier = getTypeSupplier(constructor, super::getTypes); } @Override Type[] getTypes() { - return typeSupplier.get(); + return getTypes(constructor, super::getTypes); } @Override @@ -76,13 +77,17 @@ private static boolean isGenericInformationLost(Constructor factory) { return lossDetected; } - private static Supplier getTypeSupplier(Constructor constructor, Supplier defaultSupplier) { + private static Type[] getTypes(Constructor constructor, Supplier defaultSupplier) { + return CONSTRUCTOR_CACHE.computeIfAbsent(constructor, ctor -> computeTypes(ctor, defaultSupplier)); + } + + private static Type[] computeTypes(Constructor constructor, Supplier defaultSupplier) { if (isGenericInformationLost(constructor)) { - return () -> getFields(constructor) + return getFields(constructor) .map(Field::getGenericType) .toArray(Type[]::new); } - return defaultSupplier; + return defaultSupplier.get(); } private static Stream getFields(Constructor constructor) {