DATACMNS-1698 - Reduce allocations in EntityCallbackDiscoverer.

We now detect whether callbacks are present before we create result lists instead of always allocating a Collection. CallbackRetriever now also returns a cached variant of its list of callbacks instead of always allocating a new ArrayList.
This commit is contained in:
Mark Paluch
2020-04-06 14:33:58 +02:00
parent c3b107c034
commit 461647403d

View File

@@ -19,6 +19,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Collections;
import java.util.LinkedHashSet; import java.util.LinkedHashSet;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@@ -186,7 +187,7 @@ class EntityCallbackDiscoverer {
private Collection<EntityCallback<?>> retrieveEntityCallbacks(ResolvableType entityType, ResolvableType callbackType, private Collection<EntityCallback<?>> retrieveEntityCallbacks(ResolvableType entityType, ResolvableType callbackType,
@Nullable CallbackRetriever retriever) { @Nullable CallbackRetriever retriever) {
List<EntityCallback<?>> allCallbacks = new ArrayList<>(); List<EntityCallback<?>> allCallbacks = null;
Set<EntityCallback<?>> callbacks; Set<EntityCallback<?>> callbacks;
Set<String> callbackBeans; Set<String> callbackBeans;
@@ -197,8 +198,9 @@ class EntityCallbackDiscoverer {
for (EntityCallback<?> callback : callbacks) { for (EntityCallback<?> callback : callbacks) {
if (supportsEvent(callback, entityType, callbackType)) { if (supportsEvent(callback, entityType, callbackType)) {
if (retriever != null) {
retriever.getEntityCallbacks().add(callback); if (allCallbacks == null) {
allCallbacks = new ArrayList<>();
} }
allCallbacks.add(callback); allCallbacks.add(callback);
} }
@@ -211,7 +213,9 @@ class EntityCallbackDiscoverer {
Class<?> callbackImplType = beanFactory.getType(callbackBeanName); Class<?> callbackImplType = beanFactory.getType(callbackBeanName);
if (callbackImplType == null || supportsEvent(callbackImplType, entityType)) { if (callbackImplType == null || supportsEvent(callbackImplType, entityType)) {
EntityCallback<?> callback = beanFactory.getBean(callbackBeanName, EntityCallback.class); EntityCallback<?> callback = beanFactory.getBean(callbackBeanName, EntityCallback.class);
if (!allCallbacks.contains(callback) && supportsEvent(callback, entityType, callbackType)) {
if ((allCallbacks == null || !allCallbacks.contains(callback))
&& supportsEvent(callback, entityType, callbackType)) {
if (retriever != null) { if (retriever != null) {
if (beanFactory.isSingleton(callbackBeanName)) { if (beanFactory.isSingleton(callbackBeanName)) {
retriever.entityCallbacks.add(callback); retriever.entityCallbacks.add(callback);
@@ -219,6 +223,10 @@ class EntityCallbackDiscoverer {
retriever.entityCallbackBeans.add(callbackBeanName); retriever.entityCallbackBeans.add(callbackBeanName);
} }
} }
if (allCallbacks == null) {
allCallbacks = new ArrayList<>();
}
allCallbacks.add(callback); allCallbacks.add(callback);
} }
} }
@@ -229,6 +237,10 @@ class EntityCallbackDiscoverer {
} }
} }
if (allCallbacks == null) {
return Collections.emptyList();
}
AnnotationAwareOrderComparator.sort(allCallbacks); AnnotationAwareOrderComparator.sort(allCallbacks);
if (retriever != null && retriever.entityCallbackBeans.isEmpty()) { if (retriever != null && retriever.entityCallbackBeans.isEmpty()) {
@@ -272,7 +284,7 @@ class EntityCallbackDiscoverer {
/** /**
* (non-Javadoc) * (non-Javadoc)
* *
* @see org.springframework.beans.factory.BeanClassLoaderAware * @see org.springframework.beans.factory.BeanClassLoaderAware
*/ */
public void setBeanClassLoader(ClassLoader classLoader) { public void setBeanClassLoader(ClassLoader classLoader) {
@@ -356,6 +368,8 @@ class EntityCallbackDiscoverer {
private final Set<EntityCallback<?>> entityCallbacks = new LinkedHashSet<>(); private final Set<EntityCallback<?>> entityCallbacks = new LinkedHashSet<>();
private final List<EntityCallback<?>> cachedEntityCallbacks = new ArrayList<>();
private final Set<String> entityCallbackBeans = new LinkedHashSet<>(); private final Set<String> entityCallbackBeans = new LinkedHashSet<>();
private final boolean preFiltered; private final boolean preFiltered;
@@ -366,6 +380,17 @@ class EntityCallbackDiscoverer {
Collection<EntityCallback<?>> getEntityCallbacks() { Collection<EntityCallback<?>> getEntityCallbacks() {
if (this.entityCallbackBeans.isEmpty()) {
if (cachedEntityCallbacks.size() != entityCallbacks.size()) {
cachedEntityCallbacks.clear();
cachedEntityCallbacks.addAll(entityCallbacks);
AnnotationAwareOrderComparator.sort(cachedEntityCallbacks);
}
return cachedEntityCallbacks;
}
List<EntityCallback<?>> allCallbacks = new ArrayList<>( List<EntityCallback<?>> allCallbacks = new ArrayList<>(
this.entityCallbacks.size() + this.entityCallbackBeans.size()); this.entityCallbacks.size() + this.entityCallbackBeans.size());
allCallbacks.addAll(this.entityCallbacks); allCallbacks.addAll(this.entityCallbacks);