DATACMNS-1112 - Cache instances of ReturnedType to avoid repeated reflection inspection.

We now keep instances of ReturnedType around to avoid the repeated reflection inspection for constructor and parameter name detection for class types and projection information for interfaces.
This commit is contained in:
Oliver Gierke
2017-07-12 17:09:39 +02:00
parent 4d2cc9ab8e
commit d4b79ea8f2
2 changed files with 28 additions and 3 deletions

View File

@@ -18,6 +18,7 @@ package org.springframework.data.repository.query;
import lombok.AccessLevel;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.Value;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
@@ -25,6 +26,7 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.springframework.data.mapping.PreferredConstructor;
@@ -33,6 +35,7 @@ import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.projection.ProjectionInformation;
import org.springframework.util.Assert;
import org.springframework.util.ClassUtils;
import org.springframework.util.ConcurrentReferenceHashMap;
/**
* A representation of the type returned by a {@link QueryMethod}.
@@ -44,6 +47,8 @@ import org.springframework.util.ClassUtils;
@RequiredArgsConstructor(access = AccessLevel.PRIVATE)
public abstract class ReturnedType {
private static final Map<CacheKey, ReturnedType> CACHE = new ConcurrentReferenceHashMap<>(32);
private final @NonNull Class<?> domainType;
/**
@@ -60,9 +65,12 @@ public abstract class ReturnedType {
Assert.notNull(domainType, "Domain type must not be null!");
Assert.notNull(factory, "ProjectionFactory must not be null!");
return returnedType.isInterface()
? new ReturnedInterface(factory.getProjectionInformation(returnedType), domainType)
: new ReturnedClass(returnedType, domainType);
return CACHE.computeIfAbsent(CacheKey.of(returnedType, domainType, factory.hashCode()), key -> {
return returnedType.isInterface()
? new ReturnedInterface(factory.getProjectionInformation(returnedType), domainType)
: new ReturnedClass(returnedType, domainType);
});
}
/**
@@ -316,4 +324,10 @@ public abstract class ReturnedType {
return ClassUtils.isPrimitiveOrWrapper(type);
}
}
@Value(staticConstructor = "of")
private static class CacheKey {
Class<?> returnedType, domainType;
int projectionFactoryHashCode;
}
}