Browse Source

Cache SpEL-loaded types in StandardTypeLocator

Closes gh-31579
6.0.x
Juergen Hoeller 1 year ago
parent
commit
3e06441d97
  1. 22
      spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeLocator.java

22
spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeLocator.java

@ -19,7 +19,10 @@ package org.springframework.expression.spel.support;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.springframework.core.SmartClassLoader;
import org.springframework.expression.EvaluationException; import org.springframework.expression.EvaluationException;
import org.springframework.expression.TypeLocator; import org.springframework.expression.TypeLocator;
import org.springframework.expression.spel.SpelEvaluationException; import org.springframework.expression.spel.SpelEvaluationException;
@ -48,6 +51,8 @@ public class StandardTypeLocator implements TypeLocator {
private final List<String> importPrefixes = new ArrayList<>(1); private final List<String> importPrefixes = new ArrayList<>(1);
private final Map<String, Class<?>> typeCache = new ConcurrentHashMap<>();
/** /**
* Create a {@code StandardTypeLocator} for the default {@link ClassLoader} * Create a {@code StandardTypeLocator} for the default {@link ClassLoader}
@ -110,6 +115,21 @@ public class StandardTypeLocator implements TypeLocator {
*/ */
@Override @Override
public Class<?> findType(String typeName) throws EvaluationException { public Class<?> findType(String typeName) throws EvaluationException {
Class<?> cachedType = this.typeCache.get(typeName);
if (cachedType != null) {
return cachedType;
}
Class<?> loadedType = loadType(typeName);
if (loadedType != null &&
!(this.classLoader instanceof SmartClassLoader scl && scl.isClassReloadable(loadedType))) {
this.typeCache.put(typeName, loadedType);
return loadedType;
}
throw new SpelEvaluationException(SpelMessage.TYPE_NOT_FOUND, typeName);
}
@Nullable
private Class<?> loadType(String typeName) {
try { try {
return ClassUtils.forName(typeName, this.classLoader); return ClassUtils.forName(typeName, this.classLoader);
} }
@ -125,7 +145,7 @@ public class StandardTypeLocator implements TypeLocator {
// might be a different prefix // might be a different prefix
} }
} }
throw new SpelEvaluationException(SpelMessage.TYPE_NOT_FOUND, typeName); return null;
} }
} }

Loading…
Cancel
Save