, EntityInstantiator> entityInstantiators = new HashMap<>(32);
@@ -120,12 +131,20 @@ private EntityInstantiator createEntityInstantiator(PersistentEntity, ?> entit
}
try {
- return new EntityInstantiatorAdapter(createObjectInstantiator(entity));
+ return doCreateEntityInstantiator(entity);
} catch (Throwable ex) {
return ReflectionEntityInstantiator.INSTANCE;
}
}
+ /**
+ * @param entity
+ * @return
+ */
+ protected EntityInstantiator doCreateEntityInstantiator(PersistentEntity, ?> entity) {
+ return new EntityInstantiatorAdapter(createObjectInstantiator(entity, entity.getPersistenceConstructor()));
+ }
+
/**
* @param entity
* @return
@@ -151,17 +170,46 @@ private boolean shouldUseReflectionEntityInstantiator(PersistentEntity, ?> ent
}
/**
- * Creates a dynamically generated {@link ObjectInstantiator} for the given {@link PersistentEntity}. There will
- * always be exactly one {@link ObjectInstantiator} instance per {@link PersistentEntity}.
- *
+ * Allocates an object array for instance creation. This method uses the argument array cache if possible.
+ *
+ * @param argumentCount
+ * @return
+ * @since 2.0
+ * @see #ARG_CACHE_SIZE
+ */
+ static Object[] allocateArguments(int argumentCount) {
+ return argumentCount < ARG_CACHE_SIZE ? OBJECT_POOL.get()[argumentCount] : new Object[argumentCount];
+ }
+
+ /**
+ * Deallocates an object array used for instance creation. Parameters are cleared if the array was cached.
+ *
+ * @param argumentCount
+ * @return
+ * @since 2.0
+ * @see #ARG_CACHE_SIZE
+ */
+ static void deallocateArguments(Object[] params) {
+
+ if (params.length != 0 && params.length < ARG_CACHE_SIZE) {
+ Arrays.fill(params, null);
+ }
+ }
+
+ /**
+ * Creates a dynamically generated {@link ObjectInstantiator} for the given {@link PersistentEntity} and
+ * {@link PreferredConstructor}. There will always be exactly one {@link ObjectInstantiator} instance per
+ * {@link PersistentEntity}.
*
* @param entity
+ * @param constructor
* @return
*/
- private ObjectInstantiator createObjectInstantiator(PersistentEntity, ?> entity) {
+ ObjectInstantiator createObjectInstantiator(PersistentEntity, ?> entity,
+ @Nullable PreferredConstructor, ?> constructor) {
try {
- return (ObjectInstantiator) this.generator.generateCustomInstantiatorClass(entity).newInstance();
+ return (ObjectInstantiator) this.generator.generateCustomInstantiatorClass(entity, constructor).newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
@@ -172,11 +220,10 @@ private ObjectInstantiator createObjectInstantiator(PersistentEntity, ?> entit
*
* @author Thomas Darimont
* @author Oliver Gierke
+ * @author Mark Paluch
*/
private static class EntityInstantiatorAdapter implements EntityInstantiator {
- private static final Object[] EMPTY_ARRAY = new Object[0];
-
private final ObjectInstantiator instantiator;
/**
@@ -203,6 +250,8 @@ public , P extends PersistentPrope
return (T) instantiator.newInstance(params);
} catch (Exception e) {
throw new MappingInstantiationException(entity, Arrays.asList(params), e);
+ } finally {
+ deallocateArguments(params);
}
}
@@ -216,17 +265,18 @@ public , P extends PersistentPrope
private , T> Object[] extractInvocationArguments(
@Nullable PreferredConstructor extends T, P> constructor, ParameterValueProvider
provider) {
- if (provider == null || constructor == null || !constructor.hasParameters()) {
- return EMPTY_ARRAY;
+ if (constructor == null || !constructor.hasParameters()) {
+ return allocateArguments(0);
}
- List