Skip to content

Commit 3e06441

Browse files
committed
Cache SpEL-loaded types in StandardTypeLocator
Closes gh-31579
1 parent 01f2925 commit 3e06441

File tree

1 file changed

+21
-1
lines changed

1 file changed

+21
-1
lines changed

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

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919
import java.util.ArrayList;
2020
import java.util.Collections;
2121
import java.util.List;
22+
import java.util.Map;
23+
import java.util.concurrent.ConcurrentHashMap;
2224

25+
import org.springframework.core.SmartClassLoader;
2326
import org.springframework.expression.EvaluationException;
2427
import org.springframework.expression.TypeLocator;
2528
import org.springframework.expression.spel.SpelEvaluationException;
@@ -48,6 +51,8 @@ public class StandardTypeLocator implements TypeLocator {
4851

4952
private final List<String> importPrefixes = new ArrayList<>(1);
5053

54+
private final Map<String, Class<?>> typeCache = new ConcurrentHashMap<>();
55+
5156

5257
/**
5358
* Create a {@code StandardTypeLocator} for the default {@link ClassLoader}
@@ -110,6 +115,21 @@ public List<String> getImportPrefixes() {
110115
*/
111116
@Override
112117
public Class<?> findType(String typeName) throws EvaluationException {
118+
Class<?> cachedType = this.typeCache.get(typeName);
119+
if (cachedType != null) {
120+
return cachedType;
121+
}
122+
Class<?> loadedType = loadType(typeName);
123+
if (loadedType != null &&
124+
!(this.classLoader instanceof SmartClassLoader scl && scl.isClassReloadable(loadedType))) {
125+
this.typeCache.put(typeName, loadedType);
126+
return loadedType;
127+
}
128+
throw new SpelEvaluationException(SpelMessage.TYPE_NOT_FOUND, typeName);
129+
}
130+
131+
@Nullable
132+
private Class<?> loadType(String typeName) {
113133
try {
114134
return ClassUtils.forName(typeName, this.classLoader);
115135
}
@@ -125,7 +145,7 @@ public Class<?> findType(String typeName) throws EvaluationException {
125145
// might be a different prefix
126146
}
127147
}
128-
throw new SpelEvaluationException(SpelMessage.TYPE_NOT_FOUND, typeName);
148+
return null;
129149
}
130150

131151
}

0 commit comments

Comments
 (0)