DATACMNS-332 - Performance improvements in conversion subsystem hotspots.
Added caching to DefaultTypeMapper, SimpleTypeInformationMapper, BasicPersistentEntity and PreferredConstructor as these seem to be performance hotspots on the reading side of object conversion.
This commit is contained in:
@@ -19,6 +19,8 @@ import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.data.mapping.PersistentEntity;
|
||||
import org.springframework.data.mapping.context.MappingContext;
|
||||
@@ -38,6 +40,7 @@ public class DefaultTypeMapper<S> implements TypeMapper<S> {
|
||||
|
||||
private final TypeAliasAccessor<S> accessor;
|
||||
private final List<? extends TypeInformationMapper> mappers;
|
||||
private final Map<Object, TypeInformation<?>> typeCache;
|
||||
|
||||
/**
|
||||
* Creates a new {@link DefaultTypeMapper} using the given {@link TypeAliasAccessor}. It will use a
|
||||
@@ -84,6 +87,7 @@ public class DefaultTypeMapper<S> implements TypeMapper<S> {
|
||||
|
||||
this.mappers = Collections.unmodifiableList(mappers);
|
||||
this.accessor = accessor;
|
||||
this.typeCache = new ConcurrentHashMap<Object, TypeInformation<?>>();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -93,21 +97,37 @@ public class DefaultTypeMapper<S> implements TypeMapper<S> {
|
||||
public TypeInformation<?> readType(S source) {
|
||||
|
||||
Assert.notNull(source);
|
||||
Object alias = accessor.readAliasFrom(source);
|
||||
|
||||
if (alias == null) {
|
||||
return null;
|
||||
Object alias = accessor.readAliasFrom(source);
|
||||
return alias == null ? null : getFromCacheOrCreate(alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tries to lookup a {@link TypeInformation} for the given alias from the cache and return it if found. If none is
|
||||
* found it'll consult the {@link TypeInformationMapper}s and cache the value found.
|
||||
*
|
||||
* @param alias
|
||||
* @return
|
||||
*/
|
||||
private TypeInformation<?> getFromCacheOrCreate(Object alias) {
|
||||
|
||||
TypeInformation<?> typeInformation = typeCache.get(alias);
|
||||
|
||||
if (typeInformation != null) {
|
||||
return typeInformation;
|
||||
}
|
||||
|
||||
for (TypeInformationMapper mapper : mappers) {
|
||||
TypeInformation<?> type = mapper.resolveTypeFrom(alias);
|
||||
|
||||
if (type != null) {
|
||||
return type;
|
||||
typeInformation = mapper.resolveTypeFrom(alias);
|
||||
|
||||
if (typeInformation != null) {
|
||||
typeCache.put(alias, typeInformation);
|
||||
return typeInformation;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
return typeInformation;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -15,6 +15,9 @@
|
||||
*/
|
||||
package org.springframework.data.convert;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import org.springframework.data.util.ClassTypeInformation;
|
||||
import org.springframework.data.util.TypeInformation;
|
||||
import org.springframework.util.ClassUtils;
|
||||
@@ -30,6 +33,7 @@ import org.springframework.util.StringUtils;
|
||||
public class SimpleTypeInformationMapper implements TypeInformationMapper {
|
||||
|
||||
public static final SimpleTypeInformationMapper INSTANCE = new SimpleTypeInformationMapper();
|
||||
private static final Map<String, TypeInformation<?>> cache = new ConcurrentHashMap<String, TypeInformation<?>>();
|
||||
|
||||
/**
|
||||
* Returns the {@link TypeInformation} that shall be used when the given {@link String} value is found as type hint.
|
||||
@@ -52,11 +56,23 @@ public class SimpleTypeInformationMapper implements TypeInformationMapper {
|
||||
return null;
|
||||
}
|
||||
|
||||
TypeInformation<?> information = cache.get(value);
|
||||
|
||||
if (information != null) {
|
||||
return information;
|
||||
}
|
||||
|
||||
try {
|
||||
return ClassTypeInformation.from(ClassUtils.forName(value, null));
|
||||
information = ClassTypeInformation.from(ClassUtils.forName(value, null));
|
||||
} catch (ClassNotFoundException e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (information != null) {
|
||||
cache.put(value, information);
|
||||
}
|
||||
|
||||
return information;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -67,7 +83,6 @@ public class SimpleTypeInformationMapper implements TypeInformationMapper {
|
||||
* @return the String representation to be stored or {@literal null} if no type information shall be stored.
|
||||
*/
|
||||
public String createAliasFor(TypeInformation<?> type) {
|
||||
|
||||
return type.getType().getName();
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user