From 9876aa8fd43f50cb9df7866717edc726b9913538 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 22 Mar 2024 13:16:02 +0100 Subject: [PATCH 1/4] Prepare issue branch. --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 77d72c255e..0e71ff5d11 100644 --- a/pom.xml +++ b/pom.xml @@ -5,7 +5,7 @@ org.springframework.data spring-data-commons - 3.4.0-SNAPSHOT + 3.4.x-3067-SNAPSHOT Spring Data Core Core Spring concepts underpinning every Spring Data module. From 449c876d494b97baad574bfba7eb186b61bd0c5b Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Fri, 22 Mar 2024 13:36:22 +0100 Subject: [PATCH 2/4] Aligning internal caches with core framework patterns. --- .../data/auditing/MappingAuditableBeanWrapperFactory.java | 4 ++-- .../org/springframework/data/mapping/PropertyPath.java | 4 ++-- .../data/mapping/callback/DefaultEntityCallbacks.java | 4 ++-- .../mapping/callback/DefaultReactiveEntityCallbacks.java | 4 ++-- .../data/mapping/callback/EntityCallbackDiscoverer.java | 3 +-- .../mapping/context/PersistentPropertyPathFactory.java | 4 ++-- .../data/mapping/model/BasicPersistentEntity.java | 7 +++---- .../springframework/data/mapping/model/BeanWrapper.java | 1 - .../data/mapping/model/KotlinCopyMethod.java | 4 ++-- .../projection/DefaultMethodInvokingMethodInterceptor.java | 5 ++--- .../data/projection/ProxyProjectionFactory.java | 4 ++-- .../data/querydsl/binding/QuerydslBindingsFactory.java | 4 ++-- .../EventPublishingRepositoryProxyPostProcessor.java | 4 ++-- .../repository/core/support/MethodInvocationValidator.java | 3 ++- .../repository/core/support/RepositoryComposition.java | 5 ++--- .../repository/core/support/RepositoryFactorySupport.java | 6 ++---- .../data/repository/query/ReturnedType.java | 3 ++- .../data/repository/util/QueryExecutionConverters.java | 3 +-- .../data/util/NullableWrapperConverters.java | 4 ++-- .../java/org/springframework/data/util/ParameterTypes.java | 3 ++- .../java/org/springframework/data/util/ProxyUtils.java | 4 ++-- .../org/springframework/data/util/ReactiveWrappers.java | 4 ++-- .../data/web/ProjectingJackson2HttpMessageConverter.java | 4 ++-- .../data/web/XmlBeamHttpMessageConverter.java | 5 ++--- 24 files changed, 45 insertions(+), 51 deletions(-) diff --git a/src/main/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactory.java b/src/main/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactory.java index 82d73d1610..b48659ba6e 100644 --- a/src/main/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactory.java +++ b/src/main/java/org/springframework/data/auditing/MappingAuditableBeanWrapperFactory.java @@ -19,6 +19,7 @@ import java.time.temporal.TemporalAccessor; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Predicate; import java.util.stream.Stream; @@ -40,7 +41,6 @@ import org.springframework.data.mapping.context.PersistentEntities; import org.springframework.data.util.Lazy; import org.springframework.util.Assert; -import org.springframework.util.ConcurrentReferenceHashMap; /** * {@link AuditableBeanWrapperFactory} that will create am {@link AuditableBeanWrapper} using mapping information @@ -67,7 +67,7 @@ public MappingAuditableBeanWrapperFactory(PersistentEntities entities) { Assert.notNull(entities, "PersistentEntities must not be null"); this.entities = entities; - this.metadataCache = new ConcurrentReferenceHashMap<>(); + this.metadataCache = new ConcurrentHashMap<>(); } @Override diff --git a/src/main/java/org/springframework/data/mapping/PropertyPath.java b/src/main/java/org/springframework/data/mapping/PropertyPath.java index 62b320c64a..b03a0c2bc6 100644 --- a/src/main/java/org/springframework/data/mapping/PropertyPath.java +++ b/src/main/java/org/springframework/data/mapping/PropertyPath.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Objects; import java.util.Stack; +import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -30,7 +31,6 @@ import org.springframework.data.util.TypeInformation; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.StringUtils; /** @@ -50,7 +50,7 @@ public class PropertyPath implements Streamable { private static final Pattern SPLITTER = Pattern.compile("(?:[%s]?([%s]*?[^%s]+))".replaceAll("%s", DELIMITERS)); private static final Pattern SPLITTER_FOR_QUOTED = Pattern.compile("(?:[%s]?([%s]*?[^%s]+))".replaceAll("%s", "\\.")); private static final Pattern NESTED_PROPERTY_PATTERN = Pattern.compile("\\p{Lu}[\\p{Ll}\\p{Nd}]*$"); - private static final Map cache = new ConcurrentReferenceHashMap<>(); + private static final Map cache = new ConcurrentHashMap<>(); private final TypeInformation owningType; private final String name; diff --git a/src/main/java/org/springframework/data/mapping/callback/DefaultEntityCallbacks.java b/src/main/java/org/springframework/data/mapping/callback/DefaultEntityCallbacks.java index 8bf06520b1..cfa54d1829 100644 --- a/src/main/java/org/springframework/data/mapping/callback/DefaultEntityCallbacks.java +++ b/src/main/java/org/springframework/data/mapping/callback/DefaultEntityCallbacks.java @@ -17,6 +17,7 @@ import java.lang.reflect.Method; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiFunction; import org.apache.commons.logging.Log; @@ -26,7 +27,6 @@ import org.springframework.core.ResolvableType; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ReflectionUtils; /** @@ -40,7 +40,7 @@ */ class DefaultEntityCallbacks implements EntityCallbacks { - private final Map, Method> callbackMethodCache = new ConcurrentReferenceHashMap<>(64); + private final Map, Method> callbackMethodCache = new ConcurrentHashMap<>(64); private final SimpleEntityCallbackInvoker callbackInvoker = new SimpleEntityCallbackInvoker(); private final EntityCallbackDiscoverer callbackDiscoverer; diff --git a/src/main/java/org/springframework/data/mapping/callback/DefaultReactiveEntityCallbacks.java b/src/main/java/org/springframework/data/mapping/callback/DefaultReactiveEntityCallbacks.java index d4becf3077..e61c5fac27 100644 --- a/src/main/java/org/springframework/data/mapping/callback/DefaultReactiveEntityCallbacks.java +++ b/src/main/java/org/springframework/data/mapping/callback/DefaultReactiveEntityCallbacks.java @@ -19,6 +19,7 @@ import java.lang.reflect.Method; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.BiFunction; import org.apache.commons.logging.Log; @@ -28,7 +29,6 @@ import org.springframework.core.ResolvableType; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ReflectionUtils; /** @@ -41,7 +41,7 @@ */ class DefaultReactiveEntityCallbacks implements ReactiveEntityCallbacks { - private final Map, Method> callbackMethodCache = new ConcurrentReferenceHashMap<>(64); + private final Map, Method> callbackMethodCache = new ConcurrentHashMap<>(64); private final ReactiveEntityCallbackInvoker callbackInvoker = new DefaultReactiveEntityCallbackInvoker(); private final EntityCallbackDiscoverer callbackDiscoverer; diff --git a/src/main/java/org/springframework/data/mapping/callback/EntityCallbackDiscoverer.java b/src/main/java/org/springframework/data/mapping/callback/EntityCallbackDiscoverer.java index 3e0907684f..2706a45415 100644 --- a/src/main/java/org/springframework/data/mapping/callback/EntityCallbackDiscoverer.java +++ b/src/main/java/org/springframework/data/mapping/callback/EntityCallbackDiscoverer.java @@ -38,7 +38,6 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ReflectionUtils; import org.springframework.util.comparator.Comparators; @@ -54,7 +53,7 @@ class EntityCallbackDiscoverer { private final CallbackRetriever defaultRetriever = new CallbackRetriever(); private final Map retrieverCache = new ConcurrentHashMap<>(64); - private final Map, ResolvableType> entityTypeCache = new ConcurrentReferenceHashMap<>(64); + private final Map, ResolvableType> entityTypeCache = new ConcurrentHashMap<>(64); @Nullable private ClassLoader beanClassLoader; diff --git a/src/main/java/org/springframework/data/mapping/context/PersistentPropertyPathFactory.java b/src/main/java/org/springframework/data/mapping/context/PersistentPropertyPathFactory.java index 586a832aeb..2e0ae920a4 100644 --- a/src/main/java/org/springframework/data/mapping/context/PersistentPropertyPathFactory.java +++ b/src/main/java/org/springframework/data/mapping/context/PersistentPropertyPathFactory.java @@ -16,6 +16,7 @@ package org.springframework.data.mapping.context; import java.util.*; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -33,7 +34,6 @@ import org.springframework.data.util.TypeInformation; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.StringUtils; /** @@ -49,7 +49,7 @@ class PersistentPropertyPathFactory, P extends private static final Predicate>> IS_ENTITY = PersistentProperty::isEntity; - private final Map propertyPaths = new ConcurrentReferenceHashMap<>(); + private final Map propertyPaths = new ConcurrentHashMap<>(); private final MappingContext context; public PersistentPropertyPathFactory(MappingContext context) { diff --git a/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java b/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java index edf0917225..9bf1b76760 100644 --- a/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java +++ b/src/main/java/org/springframework/data/mapping/model/BasicPersistentEntity.java @@ -27,6 +27,7 @@ import java.util.Optional; import java.util.Set; import java.util.TreeSet; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import org.springframework.core.annotation.AnnotatedElementUtils; @@ -46,8 +47,6 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.CollectionUtils; -import org.springframework.util.ConcurrentReferenceHashMap; -import org.springframework.util.ConcurrentReferenceHashMap.ReferenceType; import org.springframework.util.MultiValueMap; import org.springframework.util.StringUtils; @@ -117,9 +116,9 @@ public BasicPersistentEntity(TypeInformation information, @Nullable Comparato this.associations = comparator == null ? new HashSet<>() : new TreeSet<>(new AssociationComparator<>(comparator)); this.propertyCache = new HashMap<>(16, 1f); - this.annotationCache = new ConcurrentReferenceHashMap<>(16, ReferenceType.WEAK); + this.annotationCache = new ConcurrentHashMap<>(16); this.propertyAnnotationCache = CollectionUtils - .toMultiValueMap(new ConcurrentReferenceHashMap<>(16, ReferenceType.WEAK)); + .toMultiValueMap(new ConcurrentHashMap<>(16)); this.propertyAccessorFactory = BeanWrapperPropertyAccessorFactory.INSTANCE; this.typeAlias = Lazy.of(() -> getAliasFromAnnotation(getType())); this.isNewStrategy = Lazy.of(() -> Persistable.class.isAssignableFrom(information.getType()) // diff --git a/src/main/java/org/springframework/data/mapping/model/BeanWrapper.java b/src/main/java/org/springframework/data/mapping/model/BeanWrapper.java index 9d41eade5b..4514f23a2e 100644 --- a/src/main/java/org/springframework/data/mapping/model/BeanWrapper.java +++ b/src/main/java/org/springframework/data/mapping/model/BeanWrapper.java @@ -32,7 +32,6 @@ import org.springframework.data.util.KotlinReflectionUtils; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ReflectionUtils; /** diff --git a/src/main/java/org/springframework/data/mapping/model/KotlinCopyMethod.java b/src/main/java/org/springframework/data/mapping/model/KotlinCopyMethod.java index 951f295067..e2ea230d77 100644 --- a/src/main/java/org/springframework/data/mapping/model/KotlinCopyMethod.java +++ b/src/main/java/org/springframework/data/mapping/model/KotlinCopyMethod.java @@ -32,6 +32,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -41,7 +42,6 @@ import org.springframework.data.mapping.SimplePropertyHandler; import org.springframework.data.util.KotlinReflectionUtils; import org.springframework.util.Assert; -import org.springframework.util.ConcurrentReferenceHashMap; /** * Value object to represent a Kotlin {@code copy} method. The lookup requires a {@code copy} method that matches the @@ -53,7 +53,7 @@ */ class KotlinCopyMethod { - private static final Map, Optional> COPY_METHOD_CACHE = new ConcurrentReferenceHashMap<>(); + private static final Map, Optional> COPY_METHOD_CACHE = new ConcurrentHashMap<>(); private final Method publicCopyMethod; private final Method syntheticCopyMethod; diff --git a/src/main/java/org/springframework/data/projection/DefaultMethodInvokingMethodInterceptor.java b/src/main/java/org/springframework/data/projection/DefaultMethodInvokingMethodInterceptor.java index 457ed58881..ec73eaf83e 100644 --- a/src/main/java/org/springframework/data/projection/DefaultMethodInvokingMethodInterceptor.java +++ b/src/main/java/org/springframework/data/projection/DefaultMethodInvokingMethodInterceptor.java @@ -22,14 +22,13 @@ import java.lang.reflect.Method; import java.lang.reflect.Modifier; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.atomic.AtomicBoolean; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.ProxyMethodInvocation; import org.springframework.lang.Nullable; -import org.springframework.util.ConcurrentReferenceHashMap; -import org.springframework.util.ConcurrentReferenceHashMap.ReferenceType; import org.springframework.util.ReflectionUtils; /** @@ -43,7 +42,7 @@ public class DefaultMethodInvokingMethodInterceptor implements MethodInterceptor { private static final Lookup LOOKUP = MethodHandles.lookup(); - private final Map methodHandleCache = new ConcurrentReferenceHashMap<>(10, ReferenceType.WEAK); + private final Map methodHandleCache = new ConcurrentHashMap<>(); /** * Returns whether the {@code interfaceClass} declares {@link Method#isDefault() default methods}. diff --git a/src/main/java/org/springframework/data/projection/ProxyProjectionFactory.java b/src/main/java/org/springframework/data/projection/ProxyProjectionFactory.java index 39cab140ca..1f5271c160 100644 --- a/src/main/java/org/springframework/data/projection/ProxyProjectionFactory.java +++ b/src/main/java/org/springframework/data/projection/ProxyProjectionFactory.java @@ -20,6 +20,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; @@ -34,7 +35,6 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.ConcurrentReferenceHashMap; /** * A {@link ProjectionFactory} to create JDK proxies to back interfaces and handle method invocations on them. By @@ -60,7 +60,7 @@ class ProxyProjectionFactory implements ProjectionFactory, BeanClassLoaderAware } private final List factories; - private final Map, ProjectionMetadata> projectionInformationCache = new ConcurrentReferenceHashMap<>(); + private final Map, ProjectionMetadata> projectionInformationCache = new ConcurrentHashMap<>(); private @Nullable ClassLoader classLoader; private final Lazy defaultMethodInvokingMethodInterceptor = Lazy diff --git a/src/main/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactory.java b/src/main/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactory.java index 9b29f6ac31..a811a40950 100644 --- a/src/main/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactory.java +++ b/src/main/java/org/springframework/data/querydsl/binding/QuerydslBindingsFactory.java @@ -18,6 +18,7 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import org.springframework.beans.BeanUtils; @@ -30,7 +31,6 @@ import org.springframework.data.repository.support.Repositories; import org.springframework.data.util.TypeInformation; import org.springframework.util.Assert; -import org.springframework.util.ConcurrentReferenceHashMap; import com.querydsl.core.types.EntityPath; @@ -63,7 +63,7 @@ public QuerydslBindingsFactory(EntityPathResolver entityPathResolver) { Assert.notNull(entityPathResolver, "EntityPathResolver must not be null"); this.entityPathResolver = entityPathResolver; - this.entityPaths = new ConcurrentReferenceHashMap<>(); + this.entityPaths = new ConcurrentHashMap<>(); this.beanFactory = Optional.empty(); this.repositories = Optional.empty(); this.defaultCustomizer = NoOpCustomizer.INSTANCE; diff --git a/src/main/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessor.java b/src/main/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessor.java index 053230c7a0..714c8060f2 100644 --- a/src/main/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessor.java +++ b/src/main/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessor.java @@ -20,6 +20,7 @@ import java.util.Collection; import java.util.Collections; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; import org.aopalliance.intercept.MethodInterceptor; @@ -33,7 +34,6 @@ import org.springframework.data.util.AnnotationDetectionMethodCallback; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ReflectionUtils; /** @@ -141,7 +141,7 @@ private static boolean isDeleteMethod(String methodName) { */ static class EventPublishingMethod { - private static Map, EventPublishingMethod> cache = new ConcurrentReferenceHashMap<>(); + private static Map, EventPublishingMethod> cache = new ConcurrentHashMap<>(); private static @SuppressWarnings("null") EventPublishingMethod NONE = new EventPublishingMethod(Object.class, null, null); diff --git a/src/main/java/org/springframework/data/repository/core/support/MethodInvocationValidator.java b/src/main/java/org/springframework/data/repository/core/support/MethodInvocationValidator.java index a41e64d5ab..64fbae3c0c 100644 --- a/src/main/java/org/springframework/data/repository/core/support/MethodInvocationValidator.java +++ b/src/main/java/org/springframework/data/repository/core/support/MethodInvocationValidator.java @@ -18,6 +18,7 @@ import java.lang.annotation.ElementType; import java.lang.reflect.Method; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; @@ -49,7 +50,7 @@ public class MethodInvocationValidator implements MethodInterceptor { private final ParameterNameDiscoverer discoverer = new DefaultParameterNameDiscoverer(); - private final Map nullabilityCache = new ConcurrentReferenceHashMap<>(16, ReferenceType.WEAK); + private final Map nullabilityCache = new ConcurrentHashMap<>(16); /** * Returns {@literal true} if the {@code repositoryInterface} is supported by this interceptor. diff --git a/src/main/java/org/springframework/data/repository/core/support/RepositoryComposition.java b/src/main/java/org/springframework/data/repository/core/support/RepositoryComposition.java index e5c3a68370..d26dedf258 100644 --- a/src/main/java/org/springframework/data/repository/core/support/RepositoryComposition.java +++ b/src/main/java/org/springframework/data/repository/core/support/RepositoryComposition.java @@ -38,7 +38,6 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ObjectUtils; import org.springframework.util.ReflectionUtils; @@ -101,7 +100,7 @@ public class RepositoryComposition { private static final RepositoryComposition EMPTY = new RepositoryComposition(null, RepositoryFragments.empty(), MethodLookups.direct(), PASSTHRU_ARG_CONVERTER); - private final Map methodCache = new ConcurrentReferenceHashMap<>(); + private final Map methodCache = new ConcurrentHashMap<>(); private final RepositoryFragments fragments; private final MethodLookup methodLookup; private final BiFunction argumentConverter; @@ -365,7 +364,7 @@ public static class RepositoryFragments implements Streamable> fragmentCache = new ConcurrentReferenceHashMap<>(); + private final Map> fragmentCache = new ConcurrentHashMap<>(); private final Map invocationMetadataCache = new ConcurrentHashMap<>(); private final List> fragments; diff --git a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java index f792c1a9c8..e3531c4c9d 100644 --- a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java +++ b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java @@ -23,13 +23,13 @@ import java.util.List; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Collectors; import org.aopalliance.intercept.MethodInterceptor; import org.aopalliance.intercept.MethodInvocation; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; - import org.springframework.aop.framework.ProxyFactory; import org.springframework.aop.interceptor.ExposeInvocationInterceptor; import org.springframework.beans.BeanUtils; @@ -66,8 +66,6 @@ import org.springframework.transaction.interceptor.TransactionalProxy; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.ConcurrentReferenceHashMap; -import org.springframework.util.ConcurrentReferenceHashMap.ReferenceType; import org.springframework.util.ObjectUtils; /** @@ -110,7 +108,7 @@ public abstract class RepositoryFactorySupport implements BeanClassLoaderAware, @SuppressWarnings("null") public RepositoryFactorySupport() { - this.repositoryInformationCache = new ConcurrentReferenceHashMap<>(16, ReferenceType.WEAK); + this.repositoryInformationCache = new ConcurrentHashMap<>(16); this.postProcessors = new ArrayList<>(); this.repositoryBaseClass = Optional.empty(); diff --git a/src/main/java/org/springframework/data/repository/query/ReturnedType.java b/src/main/java/org/springframework/data/repository/query/ReturnedType.java index 796a6acdd0..04af513757 100644 --- a/src/main/java/org/springframework/data/repository/query/ReturnedType.java +++ b/src/main/java/org/springframework/data/repository/query/ReturnedType.java @@ -23,6 +23,7 @@ import java.util.List; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.data.mapping.Parameter; import org.springframework.data.mapping.PreferredConstructor; @@ -46,7 +47,7 @@ */ public abstract class ReturnedType { - private static final Map cache = new ConcurrentReferenceHashMap<>(32); + private static final Map cache = new ConcurrentHashMap<>(32); private final Class domainType; diff --git a/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java b/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java index 514fd15414..5aa8df8dc8 100644 --- a/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java +++ b/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java @@ -49,7 +49,6 @@ import org.springframework.scheduling.annotation.AsyncResult; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ObjectUtils; import org.springframework.util.concurrent.ListenableFuture; @@ -84,7 +83,7 @@ public abstract class QueryExecutionConverters { private static final Set> UNWRAPPERS = new HashSet<>(); private static final Set> ALLOWED_PAGEABLE_TYPES = new HashSet<>(); private static final Map, ExecutionAdapter> EXECUTION_ADAPTER = new HashMap<>(); - private static final Map, Boolean> supportsCache = new ConcurrentReferenceHashMap<>(); + private static final Map, Boolean> supportsCache = new ConcurrentHashMap<>(); private static final TypeInformation VOID_INFORMATION = TypeInformation.of(Void.class); static { diff --git a/src/main/java/org/springframework/data/util/NullableWrapperConverters.java b/src/main/java/org/springframework/data/util/NullableWrapperConverters.java index 044198c905..f83b877e4c 100644 --- a/src/main/java/org/springframework/data/util/NullableWrapperConverters.java +++ b/src/main/java/org/springframework/data/util/NullableWrapperConverters.java @@ -23,6 +23,7 @@ import java.util.HashSet; import java.util.Map; import java.util.Set; +import java.util.concurrent.ConcurrentHashMap; import java.util.stream.Stream; import org.springframework.core.convert.TypeDescriptor; @@ -32,7 +33,6 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ObjectUtils; import com.google.common.base.Optional; @@ -67,7 +67,7 @@ public abstract class NullableWrapperConverters { private static final Set WRAPPER_TYPES = new HashSet(); private static final Set UNWRAPPER_TYPES = new HashSet(); private static final Set> UNWRAPPERS = new HashSet>(); - private static final Map, Boolean> supportsCache = new ConcurrentReferenceHashMap<>(); + private static final Map, Boolean> supportsCache = new ConcurrentHashMap<>(); static { diff --git a/src/main/java/org/springframework/data/util/ParameterTypes.java b/src/main/java/org/springframework/data/util/ParameterTypes.java index e6a927588c..18b2cb5f9c 100644 --- a/src/main/java/org/springframework/data/util/ParameterTypes.java +++ b/src/main/java/org/springframework/data/util/ParameterTypes.java @@ -22,6 +22,7 @@ import java.util.Collections; import java.util.List; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.stream.Collectors; @@ -45,7 +46,7 @@ public class ParameterTypes { private static final TypeDescriptor OBJECT_DESCRIPTOR = TypeDescriptor.valueOf(Object.class); - private static final ConcurrentMap, ParameterTypes> cache = new ConcurrentReferenceHashMap<>(); + private static final ConcurrentMap, ParameterTypes> cache = new ConcurrentHashMap<>(); private final List types; private final Lazy> alternatives; diff --git a/src/main/java/org/springframework/data/util/ProxyUtils.java b/src/main/java/org/springframework/data/util/ProxyUtils.java index eee2c47104..d690ce1538 100644 --- a/src/main/java/org/springframework/data/util/ProxyUtils.java +++ b/src/main/java/org/springframework/data/util/ProxyUtils.java @@ -17,12 +17,12 @@ import java.util.List; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.aop.support.AopUtils; import org.springframework.core.io.support.SpringFactoriesLoader; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.ConcurrentReferenceHashMap; /** * Proxy type detection utilities, extensible via {@link ProxyDetector} registered via Spring factories. @@ -32,7 +32,7 @@ */ public abstract class ProxyUtils { - private static Map, Class> USER_TYPES = new ConcurrentReferenceHashMap<>(); + private static Map, Class> USER_TYPES = new ConcurrentHashMap<>(); private static final List DETECTORS = SpringFactoriesLoader.loadFactories(ProxyDetector.class, ProxyUtils.class.getClassLoader()); diff --git a/src/main/java/org/springframework/data/util/ReactiveWrappers.java b/src/main/java/org/springframework/data/util/ReactiveWrappers.java index 6802918b1c..12f7f600cc 100644 --- a/src/main/java/org/springframework/data/util/ReactiveWrappers.java +++ b/src/main/java/org/springframework/data/util/ReactiveWrappers.java @@ -21,6 +21,7 @@ import java.util.Arrays; import java.util.Map; import java.util.Optional; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; @@ -28,7 +29,6 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; -import org.springframework.util.ConcurrentReferenceHashMap; /** * Utility class to expose details about reactive wrapper types. This class exposes whether a reactive wrapper is @@ -70,7 +70,7 @@ public abstract class ReactiveWrappers { public static final boolean IS_REACTIVE_AVAILABLE = Arrays.stream(ReactiveLibrary.values()) .anyMatch(ReactiveWrappers::isAvailable); - private static final Map, Boolean> IS_REACTIVE_TYPE = new ConcurrentReferenceHashMap<>(); + private static final Map, Boolean> IS_REACTIVE_TYPE = new ConcurrentHashMap<>(); private ReactiveWrappers() {} diff --git a/src/main/java/org/springframework/data/web/ProjectingJackson2HttpMessageConverter.java b/src/main/java/org/springframework/data/web/ProjectingJackson2HttpMessageConverter.java index 2b5fb5de24..c818b6afc1 100644 --- a/src/main/java/org/springframework/data/web/ProjectingJackson2HttpMessageConverter.java +++ b/src/main/java/org/springframework/data/web/ProjectingJackson2HttpMessageConverter.java @@ -18,6 +18,7 @@ import java.io.IOException; import java.lang.reflect.Type; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanClassLoaderAware; @@ -33,7 +34,6 @@ import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ConcurrentReferenceHashMap; import com.fasterxml.jackson.databind.ObjectMapper; import com.jayway.jsonpath.spi.json.JacksonJsonProvider; @@ -52,7 +52,7 @@ public class ProjectingJackson2HttpMessageConverter extends MappingJackson2HttpM implements BeanClassLoaderAware, BeanFactoryAware { private final SpelAwareProxyProjectionFactory projectionFactory; - private final Map, Boolean> supportedTypesCache = new ConcurrentReferenceHashMap<>(); + private final Map, Boolean> supportedTypesCache = new ConcurrentHashMap<>(); /** * Creates a new {@link ProjectingJackson2HttpMessageConverter} using a default {@link ObjectMapper}. diff --git a/src/main/java/org/springframework/data/web/XmlBeamHttpMessageConverter.java b/src/main/java/org/springframework/data/web/XmlBeamHttpMessageConverter.java index 9167836bdb..7db27e6746 100644 --- a/src/main/java/org/springframework/data/web/XmlBeamHttpMessageConverter.java +++ b/src/main/java/org/springframework/data/web/XmlBeamHttpMessageConverter.java @@ -17,6 +17,7 @@ import java.io.IOException; import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; import javax.xml.parsers.DocumentBuilderFactory; @@ -31,8 +32,6 @@ import org.springframework.http.converter.HttpMessageNotWritableException; import org.springframework.lang.Nullable; import org.springframework.util.Assert; -import org.springframework.util.ConcurrentReferenceHashMap; - import org.xml.sax.SAXParseException; import org.xmlbeam.XBProjector; import org.xmlbeam.config.DefaultXMLFactoriesConfig; @@ -49,7 +48,7 @@ public class XmlBeamHttpMessageConverter extends AbstractHttpMessageConverter { private final XBProjector projectionFactory; - private final Map, Boolean> supportedTypesCache = new ConcurrentReferenceHashMap<>(); + private final Map, Boolean> supportedTypesCache = new ConcurrentHashMap<>(); /** * Creates a new {@link XmlBeamHttpMessageConverter}. From 850b25aaccbd47200c3cbe7aa25a556695afeed5 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 20 Mar 2024 10:47:51 +0100 Subject: [PATCH 3/4] Initialize maps & sets with size where possible. --- .../convert/SimplePropertyValueConverterRegistry.java | 8 +++++--- .../org/springframework/data/domain/ExampleMatcher.java | 8 +++++--- .../data/geo/format/DistanceFormatter.java | 2 +- .../data/mapping/context/AbstractMappingContext.java | 2 +- .../model/ClassGeneratingPropertyAccessorFactory.java | 2 +- .../data/projection/SpelEvaluatingMethodInterceptor.java | 5 +++-- .../core/support/QueryExecutorMethodInterceptor.java | 5 +++-- .../repository/core/support/RepositoryFactorySupport.java | 2 +- ...xtensionAwareQueryMethodEvaluationContextProvider.java | 2 +- .../data/repository/util/QueryExecutionConverters.java | 6 +++--- .../springframework/data/util/KotlinBeanInfoFactory.java | 6 ++++-- .../java/org/springframework/data/util/TypeCollector.java | 2 +- 12 files changed, 29 insertions(+), 21 deletions(-) diff --git a/src/main/java/org/springframework/data/convert/SimplePropertyValueConverterRegistry.java b/src/main/java/org/springframework/data/convert/SimplePropertyValueConverterRegistry.java index 50adf3fbac..560b5cdbab 100644 --- a/src/main/java/org/springframework/data/convert/SimplePropertyValueConverterRegistry.java +++ b/src/main/java/org/springframework/data/convert/SimplePropertyValueConverterRegistry.java @@ -32,12 +32,14 @@ public class SimplePropertyValueConverterRegistry

> implements ValueConverterRegistry

{ - private final Map>> converterRegistrationMap = new LinkedHashMap<>(); + private final Map>> converterRegistrationMap; - public SimplePropertyValueConverterRegistry() {} + public SimplePropertyValueConverterRegistry() { + this.converterRegistrationMap = new LinkedHashMap<>(); + } SimplePropertyValueConverterRegistry(SimplePropertyValueConverterRegistry

source) { - this.converterRegistrationMap.putAll(source.converterRegistrationMap); + this.converterRegistrationMap = new LinkedHashMap<>(source.converterRegistrationMap); } @Override diff --git a/src/main/java/org/springframework/data/domain/ExampleMatcher.java b/src/main/java/org/springframework/data/domain/ExampleMatcher.java index f152db25cc..3d716fc11a 100644 --- a/src/main/java/org/springframework/data/domain/ExampleMatcher.java +++ b/src/main/java/org/springframework/data/domain/ExampleMatcher.java @@ -775,12 +775,14 @@ protected boolean canEqual(final Object other) { */ class PropertySpecifiers { - private final Map propertySpecifiers = new LinkedHashMap<>(); + private final Map propertySpecifiers; - PropertySpecifiers() {} + PropertySpecifiers() { + this. propertySpecifiers = new LinkedHashMap<>(); + } PropertySpecifiers(PropertySpecifiers propertySpecifiers) { - this.propertySpecifiers.putAll(propertySpecifiers.propertySpecifiers); + this.propertySpecifiers = new LinkedHashMap<>(propertySpecifiers.propertySpecifiers); } public void add(PropertySpecifier specifier) { diff --git a/src/main/java/org/springframework/data/geo/format/DistanceFormatter.java b/src/main/java/org/springframework/data/geo/format/DistanceFormatter.java index 7246b8c5b0..a28626bd54 100644 --- a/src/main/java/org/springframework/data/geo/format/DistanceFormatter.java +++ b/src/main/java/org/springframework/data/geo/format/DistanceFormatter.java @@ -47,7 +47,7 @@ public enum DistanceFormatter implements Converter, Formatter< static { - Map metrics = new LinkedHashMap<>(); + Map metrics = new LinkedHashMap<>(Metrics.values().length); for (Metric metric : Metrics.values()) { metrics.put(metric.getAbbreviation(), metric); diff --git a/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java b/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java index d6f2a2b6d4..4755f165c9 100644 --- a/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java +++ b/src/main/java/org/springframework/data/mapping/context/AbstractMappingContext.java @@ -461,7 +461,7 @@ private E doAddPersistentEntity(TypeInformation typeInformation) { if (shouldCreateProperties(userTypeInformation)) { PropertyDescriptor[] pds = BeanUtils.getPropertyDescriptors(type); - Map descriptors = new HashMap<>(); + Map descriptors = new HashMap<>(pds.length); for (PropertyDescriptor descriptor : pds) { descriptors.put(descriptor.getName(), descriptor); diff --git a/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java b/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java index eefbed43b7..3ab3e04113 100644 --- a/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java +++ b/src/main/java/org/springframework/data/mapping/model/ClassGeneratingPropertyAccessorFactory.java @@ -1395,7 +1395,7 @@ private static int getInvokeOp(Method method, boolean interfaceDefinition) { private static Map createPropertyStackMap( List> persistentProperties) { - Map stackmap = new HashMap<>(); + Map stackmap = new HashMap<>(persistentProperties.size()); for (PersistentProperty property : persistentProperties) { stackmap.put(property.getName(), new PropertyStackAddress(new Label(), property.getName().hashCode())); diff --git a/src/main/java/org/springframework/data/projection/SpelEvaluatingMethodInterceptor.java b/src/main/java/org/springframework/data/projection/SpelEvaluatingMethodInterceptor.java index c5d5fc3641..52be16cc72 100644 --- a/src/main/java/org/springframework/data/projection/SpelEvaluatingMethodInterceptor.java +++ b/src/main/java/org/springframework/data/projection/SpelEvaluatingMethodInterceptor.java @@ -107,9 +107,10 @@ public SpelEvaluatingMethodInterceptor(MethodInterceptor delegate, Object target private static Map potentiallyCreateExpressionsForMethodsOnTargetInterface( ExpressionParser parser, Class targetInterface) { - Map expressions = new HashMap<>(); + Method[] methods = targetInterface.getMethods(); + Map expressions = new HashMap<>(methods.length); - for (Method method : targetInterface.getMethods()) { + for (Method method : methods) { Value value = AnnotationUtils.findAnnotation(method, Value.class); if (value == null) { diff --git a/src/main/java/org/springframework/data/repository/core/support/QueryExecutorMethodInterceptor.java b/src/main/java/org/springframework/data/repository/core/support/QueryExecutorMethodInterceptor.java index d61785a2b6..4b3f609da3 100644 --- a/src/main/java/org/springframework/data/repository/core/support/QueryExecutorMethodInterceptor.java +++ b/src/main/java/org/springframework/data/repository/core/support/QueryExecutorMethodInterceptor.java @@ -92,9 +92,10 @@ public QueryExecutorMethodInterceptor(RepositoryInformation repositoryInformatio private Map mapMethodsToQuery(RepositoryInformation repositoryInformation, QueryLookupStrategy lookupStrategy, ProjectionFactory projectionFactory) { - Map result = new HashMap<>(); + List queryMethods = repositoryInformation.getQueryMethods().toList(); + Map result = new HashMap<>(queryMethods.size()); - for (Method method : repositoryInformation.getQueryMethods()) { + for (Method method : queryMethods) { Pair pair = lookupQuery(method, repositoryInformation, lookupStrategy, projectionFactory); diff --git a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java index e3531c4c9d..13274805a7 100644 --- a/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java +++ b/src/main/java/org/springframework/data/repository/core/support/RepositoryFactorySupport.java @@ -725,7 +725,7 @@ public String toString() { */ static class RepositoryValidator { - static Map, String> WELL_KNOWN_EXECUTORS = new HashMap<>(); + static Map, String> WELL_KNOWN_EXECUTORS = new HashMap<>(4, 1f); static { diff --git a/src/main/java/org/springframework/data/repository/query/ExtensionAwareQueryMethodEvaluationContextProvider.java b/src/main/java/org/springframework/data/repository/query/ExtensionAwareQueryMethodEvaluationContextProvider.java index f4adae72ef..44cd3f655c 100644 --- a/src/main/java/org/springframework/data/repository/query/ExtensionAwareQueryMethodEvaluationContextProvider.java +++ b/src/main/java/org/springframework/data/repository/query/ExtensionAwareQueryMethodEvaluationContextProvider.java @@ -100,7 +100,7 @@ public ExtensionAwareQueryMethodEvaluationContextProvider(List collectVariables(Parameters parameters, Object[] arguments) { - Map variables = new HashMap<>(); + Map variables = new HashMap<>(parameters.getNumberOfParameters()); parameters.stream()// .filter(Parameter::isSpecialParameter)// diff --git a/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java b/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java index 5aa8df8dc8..a2ee0e7703 100644 --- a/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java +++ b/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java @@ -78,11 +78,11 @@ public abstract class QueryExecutionConverters { private static final boolean VAVR_PRESENT = ClassUtils.isPresent("io.vavr.control.Try", QueryExecutionConverters.class.getClassLoader()); - private static final Set WRAPPER_TYPES = new HashSet<>(); - private static final Set UNWRAPPER_TYPES = new HashSet(); + private static final Set WRAPPER_TYPES = new HashSet<>(10, 1f); + private static final Set UNWRAPPER_TYPES = new HashSet(10, 1f); private static final Set> UNWRAPPERS = new HashSet<>(); private static final Set> ALLOWED_PAGEABLE_TYPES = new HashSet<>(); - private static final Map, ExecutionAdapter> EXECUTION_ADAPTER = new HashMap<>(); + private static final Map, ExecutionAdapter> EXECUTION_ADAPTER = new HashMap<>(3, 1f); private static final Map, Boolean> supportsCache = new ConcurrentHashMap<>(); private static final TypeInformation VOID_INFORMATION = TypeInformation.of(Void.class); diff --git a/src/main/java/org/springframework/data/util/KotlinBeanInfoFactory.java b/src/main/java/org/springframework/data/util/KotlinBeanInfoFactory.java index eab80c9bc7..f7d00fc091 100644 --- a/src/main/java/org/springframework/data/util/KotlinBeanInfoFactory.java +++ b/src/main/java/org/springframework/data/util/KotlinBeanInfoFactory.java @@ -29,6 +29,7 @@ import java.beans.SimpleBeanInfo; import java.lang.reflect.Method; import java.util.Arrays; +import java.util.Collection; import java.util.LinkedHashSet; import java.util.Set; @@ -59,9 +60,10 @@ public BeanInfo getBeanInfo(Class beanClass) throws IntrospectionException { } KClass kotlinClass = JvmClassMappingKt.getKotlinClass(beanClass); - Set pds = new LinkedHashSet<>(); + Collection> members = kotlinClass.getMembers(); + Set pds = new LinkedHashSet<>(members.size()); - for (KCallable member : kotlinClass.getMembers()) { + for (KCallable member : members) { if (member instanceof KProperty property) { diff --git a/src/main/java/org/springframework/data/util/TypeCollector.java b/src/main/java/org/springframework/data/util/TypeCollector.java index fb42eb0451..6d179d88aa 100644 --- a/src/main/java/org/springframework/data/util/TypeCollector.java +++ b/src/main/java/org/springframework/data/util/TypeCollector.java @@ -242,7 +242,7 @@ private List> collect() { static class InspectionCache { - private final Map mutableCache = new LinkedHashMap<>(); + private final Map mutableCache = new HashMap<>(); public void add(ResolvableType resolvableType) { mutableCache.put(resolvableType.toString(), resolvableType); From 452fdffab7febc342f94a4951dc41e20beadf066 Mon Sep 17 00:00:00 2001 From: Christoph Strobl Date: Wed, 12 Jun 2024 16:25:34 +0200 Subject: [PATCH 4/4] Revert some changes after review --- .../java/org/springframework/data/mapping/PropertyPath.java | 4 ++-- .../springframework/data/mapping/model/KotlinCopyMethod.java | 4 ++-- .../support/EventPublishingRepositoryProxyPostProcessor.java | 4 ++-- .../springframework/data/repository/query/ReturnedType.java | 3 +-- .../data/repository/util/QueryExecutionConverters.java | 3 ++- .../java/org/springframework/data/util/ParameterTypes.java | 3 +-- src/main/java/org/springframework/data/util/ProxyUtils.java | 4 ++-- .../java/org/springframework/data/util/ReactiveWrappers.java | 4 ++-- 8 files changed, 14 insertions(+), 15 deletions(-) diff --git a/src/main/java/org/springframework/data/mapping/PropertyPath.java b/src/main/java/org/springframework/data/mapping/PropertyPath.java index b03a0c2bc6..62b320c64a 100644 --- a/src/main/java/org/springframework/data/mapping/PropertyPath.java +++ b/src/main/java/org/springframework/data/mapping/PropertyPath.java @@ -23,7 +23,6 @@ import java.util.Map; import java.util.Objects; import java.util.Stack; -import java.util.concurrent.ConcurrentHashMap; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -31,6 +30,7 @@ import org.springframework.data.util.TypeInformation; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.StringUtils; /** @@ -50,7 +50,7 @@ public class PropertyPath implements Streamable { private static final Pattern SPLITTER = Pattern.compile("(?:[%s]?([%s]*?[^%s]+))".replaceAll("%s", DELIMITERS)); private static final Pattern SPLITTER_FOR_QUOTED = Pattern.compile("(?:[%s]?([%s]*?[^%s]+))".replaceAll("%s", "\\.")); private static final Pattern NESTED_PROPERTY_PATTERN = Pattern.compile("\\p{Lu}[\\p{Ll}\\p{Nd}]*$"); - private static final Map cache = new ConcurrentHashMap<>(); + private static final Map cache = new ConcurrentReferenceHashMap<>(); private final TypeInformation owningType; private final String name; diff --git a/src/main/java/org/springframework/data/mapping/model/KotlinCopyMethod.java b/src/main/java/org/springframework/data/mapping/model/KotlinCopyMethod.java index e2ea230d77..951f295067 100644 --- a/src/main/java/org/springframework/data/mapping/model/KotlinCopyMethod.java +++ b/src/main/java/org/springframework/data/mapping/model/KotlinCopyMethod.java @@ -32,7 +32,6 @@ import java.util.List; import java.util.Map; import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.Predicate; import java.util.stream.Collectors; @@ -42,6 +41,7 @@ import org.springframework.data.mapping.SimplePropertyHandler; import org.springframework.data.util.KotlinReflectionUtils; import org.springframework.util.Assert; +import org.springframework.util.ConcurrentReferenceHashMap; /** * Value object to represent a Kotlin {@code copy} method. The lookup requires a {@code copy} method that matches the @@ -53,7 +53,7 @@ */ class KotlinCopyMethod { - private static final Map, Optional> COPY_METHOD_CACHE = new ConcurrentHashMap<>(); + private static final Map, Optional> COPY_METHOD_CACHE = new ConcurrentReferenceHashMap<>(); private final Method publicCopyMethod; private final Method syntheticCopyMethod; diff --git a/src/main/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessor.java b/src/main/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessor.java index 714c8060f2..053230c7a0 100644 --- a/src/main/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessor.java +++ b/src/main/java/org/springframework/data/repository/core/support/EventPublishingRepositoryProxyPostProcessor.java @@ -20,7 +20,6 @@ import java.util.Collection; import java.util.Collections; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import java.util.function.Supplier; import org.aopalliance.intercept.MethodInterceptor; @@ -34,6 +33,7 @@ import org.springframework.data.util.AnnotationDetectionMethodCallback; import org.springframework.lang.Nullable; import org.springframework.util.Assert; +import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ReflectionUtils; /** @@ -141,7 +141,7 @@ private static boolean isDeleteMethod(String methodName) { */ static class EventPublishingMethod { - private static Map, EventPublishingMethod> cache = new ConcurrentHashMap<>(); + private static Map, EventPublishingMethod> cache = new ConcurrentReferenceHashMap<>(); private static @SuppressWarnings("null") EventPublishingMethod NONE = new EventPublishingMethod(Object.class, null, null); diff --git a/src/main/java/org/springframework/data/repository/query/ReturnedType.java b/src/main/java/org/springframework/data/repository/query/ReturnedType.java index 04af513757..796a6acdd0 100644 --- a/src/main/java/org/springframework/data/repository/query/ReturnedType.java +++ b/src/main/java/org/springframework/data/repository/query/ReturnedType.java @@ -23,7 +23,6 @@ import java.util.List; import java.util.Map; import java.util.Set; -import java.util.concurrent.ConcurrentHashMap; import org.springframework.data.mapping.Parameter; import org.springframework.data.mapping.PreferredConstructor; @@ -47,7 +46,7 @@ */ public abstract class ReturnedType { - private static final Map cache = new ConcurrentHashMap<>(32); + private static final Map cache = new ConcurrentReferenceHashMap<>(32); private final Class domainType; diff --git a/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java b/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java index a2ee0e7703..17aaf56471 100644 --- a/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java +++ b/src/main/java/org/springframework/data/repository/util/QueryExecutionConverters.java @@ -49,6 +49,7 @@ import org.springframework.scheduling.annotation.AsyncResult; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.ConcurrentReferenceHashMap; import org.springframework.util.ObjectUtils; import org.springframework.util.concurrent.ListenableFuture; @@ -83,7 +84,7 @@ public abstract class QueryExecutionConverters { private static final Set> UNWRAPPERS = new HashSet<>(); private static final Set> ALLOWED_PAGEABLE_TYPES = new HashSet<>(); private static final Map, ExecutionAdapter> EXECUTION_ADAPTER = new HashMap<>(3, 1f); - private static final Map, Boolean> supportsCache = new ConcurrentHashMap<>(); + private static final Map, Boolean> supportsCache = new ConcurrentReferenceHashMap<>(); private static final TypeInformation VOID_INFORMATION = TypeInformation.of(Void.class); static { diff --git a/src/main/java/org/springframework/data/util/ParameterTypes.java b/src/main/java/org/springframework/data/util/ParameterTypes.java index 18b2cb5f9c..e6a927588c 100644 --- a/src/main/java/org/springframework/data/util/ParameterTypes.java +++ b/src/main/java/org/springframework/data/util/ParameterTypes.java @@ -22,7 +22,6 @@ import java.util.Collections; import java.util.List; import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; import java.util.stream.Collectors; @@ -46,7 +45,7 @@ public class ParameterTypes { private static final TypeDescriptor OBJECT_DESCRIPTOR = TypeDescriptor.valueOf(Object.class); - private static final ConcurrentMap, ParameterTypes> cache = new ConcurrentHashMap<>(); + private static final ConcurrentMap, ParameterTypes> cache = new ConcurrentReferenceHashMap<>(); private final List types; private final Lazy> alternatives; diff --git a/src/main/java/org/springframework/data/util/ProxyUtils.java b/src/main/java/org/springframework/data/util/ProxyUtils.java index d690ce1538..eee2c47104 100644 --- a/src/main/java/org/springframework/data/util/ProxyUtils.java +++ b/src/main/java/org/springframework/data/util/ProxyUtils.java @@ -17,12 +17,12 @@ import java.util.List; import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; import org.springframework.aop.support.AopUtils; import org.springframework.core.io.support.SpringFactoriesLoader; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.ConcurrentReferenceHashMap; /** * Proxy type detection utilities, extensible via {@link ProxyDetector} registered via Spring factories. @@ -32,7 +32,7 @@ */ public abstract class ProxyUtils { - private static Map, Class> USER_TYPES = new ConcurrentHashMap<>(); + private static Map, Class> USER_TYPES = new ConcurrentReferenceHashMap<>(); private static final List DETECTORS = SpringFactoriesLoader.loadFactories(ProxyDetector.class, ProxyUtils.class.getClassLoader()); diff --git a/src/main/java/org/springframework/data/util/ReactiveWrappers.java b/src/main/java/org/springframework/data/util/ReactiveWrappers.java index 12f7f600cc..6802918b1c 100644 --- a/src/main/java/org/springframework/data/util/ReactiveWrappers.java +++ b/src/main/java/org/springframework/data/util/ReactiveWrappers.java @@ -21,7 +21,6 @@ import java.util.Arrays; import java.util.Map; import java.util.Optional; -import java.util.concurrent.ConcurrentHashMap; import org.springframework.core.ReactiveAdapter; import org.springframework.core.ReactiveAdapterRegistry; @@ -29,6 +28,7 @@ import org.springframework.lang.Nullable; import org.springframework.util.Assert; import org.springframework.util.ClassUtils; +import org.springframework.util.ConcurrentReferenceHashMap; /** * Utility class to expose details about reactive wrapper types. This class exposes whether a reactive wrapper is @@ -70,7 +70,7 @@ public abstract class ReactiveWrappers { public static final boolean IS_REACTIVE_AVAILABLE = Arrays.stream(ReactiveLibrary.values()) .anyMatch(ReactiveWrappers::isAvailable); - private static final Map, Boolean> IS_REACTIVE_TYPE = new ConcurrentHashMap<>(); + private static final Map, Boolean> IS_REACTIVE_TYPE = new ConcurrentReferenceHashMap<>(); private ReactiveWrappers() {}