DATACMNS-1101 - Reduce Optional usage in convert/mapping packages.

Reducing Optional usage that lies on hot code paths for object mapping.
This commit is contained in:
Mark Paluch
2017-06-26 15:49:47 +02:00
committed by Oliver Gierke
parent 4aa083377b
commit 74fbe13f54
42 changed files with 428 additions and 427 deletions

View File

@@ -49,6 +49,7 @@ import org.springframework.util.ClassUtils;
* @author Oliver Gierke
* @author Phillip Webb
* @author Christoph Strobl
* @author Mark Paluch
* @since 1.11
*/
public class ClassGeneratingEntityInstantiator implements EntityInstantiator {
@@ -64,7 +65,7 @@ public class ClassGeneratingEntityInstantiator implements EntityInstantiator {
this.generator = new ObjectInstantiatorClassGenerator();
}
/*
/*
* (non-Javadoc)
* @see org.springframework.data.convert.EntityInstantiator#createInstance(org.springframework.data.mapping.PersistentEntity, org.springframework.data.mapping.model.ParameterValueProvider)
*/
@@ -196,7 +197,7 @@ public class ClassGeneratingEntityInstantiator implements EntityInstantiator {
try {
return (T) instantiator.newInstance(params);
} catch (Exception e) {
throw new MappingInstantiationException(Optional.of(entity), Arrays.asList(params), e);
throw new MappingInstantiationException(entity, Arrays.asList(params), e);
}
}
@@ -218,7 +219,6 @@ public class ClassGeneratingEntityInstantiator implements EntityInstantiator {
return it.getParameters().stream()//
.map(provider::getParameterValue)//
.map(value -> value.orElse(null))//
.toArray();
}).orElse(EMPTY_ARRAY);
@@ -227,7 +227,7 @@ public class ClassGeneratingEntityInstantiator implements EntityInstantiator {
/**
* Needs to be public as otherwise the implementation class generated does not see the interface from the classloader.
*
*
* @author Thomas Darimont
* @author Oliver Gierke
*/

View File

@@ -19,23 +19,22 @@ import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import org.springframework.beans.BeanInstantiationException;
import org.springframework.beans.BeanUtils;
import org.springframework.data.mapping.PersistentEntity;
import org.springframework.data.mapping.PersistentProperty;
import org.springframework.data.mapping.PreferredConstructor;
import org.springframework.data.mapping.PreferredConstructor.Parameter;
import org.springframework.data.mapping.model.MappingInstantiationException;
import org.springframework.data.mapping.model.ParameterValueProvider;
/**
* {@link EntityInstantiator} that uses the {@link PersistentEntity}'s {@link PreferredConstructor} to instantiate an
* instance of the entity via reflection.
*
*
* @author Oliver Gierke
* @author Christoph Strobl
* @author Mark Paluch
*/
public enum ReflectionEntityInstantiator implements EntityInstantiator {
@@ -45,51 +44,39 @@ public enum ReflectionEntityInstantiator implements EntityInstantiator {
public <T, E extends PersistentEntity<? extends T, P>, P extends PersistentProperty<P>> T createInstance(E entity,
ParameterValueProvider<P> provider) {
return entity.getPersistenceConstructor().map(constructor -> {
PreferredConstructor<? extends T, P> constructor = entity.getPersistenceConstructor().orElse(null);
List<Object> params = Optional.ofNullable(provider)//
.map(it -> constructor.getParameters().stream()//
.map(parameter -> it.getParameterValue(parameter).orElse(Optional.empty()))//
.collect(Collectors.toList()))//
.orElseGet(Collections::emptyList);
List<Object> foo = new ArrayList<>(params.size());
for (Object element : params) {
foo.add((element instanceof Optional) ? null : element);
}
if (constructor == null) {
try {
return (T) BeanUtils.instantiateClass(constructor.getConstructor(), foo.toArray());
} catch (BeanInstantiationException e) {
throw new MappingInstantiationException(Optional.of(entity), params, e);
}
}).orElseGet(() -> {
try {
Class<? extends T> clazz = entity.getType();
Class<?> clazz = entity.getType();
if (clazz.isArray()) {
Class<?> ctype = clazz;
int dims = 0;
while (ctype.isArray()) {
ctype = ctype.getComponentType();
dims++;
}
return (T) Array.newInstance(clazz, dims);
} else {
return BeanUtils.instantiateClass(clazz);
return BeanUtils.instantiateClass(entity.getType());
}
} catch (BeanInstantiationException e) {
throw new MappingInstantiationException(Optional.of(entity), Collections.emptyList(), e);
throw new MappingInstantiationException(entity, Collections.emptyList(), e);
}
});
}
List<Object> params = new ArrayList<>();
if (null != provider && constructor.hasParameters()) {
for (Parameter<?, P> parameter : constructor.getParameters()) {
params.add(provider.getParameterValue(parameter));
}
}
try {
return BeanUtils.instantiateClass(constructor.getConstructor(), params.toArray());
} catch (BeanInstantiationException e) {
throw new MappingInstantiationException(entity, params, e);
}
}
}