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:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user