@ -19,7 +19,10 @@ package org.springframework.expression.spel.support;
@@ -19,7 +19,10 @@ package org.springframework.expression.spel.support;
import java.util.ArrayList ;
import java.util.Collections ;
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.TypeLocator ;
import org.springframework.expression.spel.SpelEvaluationException ;
@ -48,6 +51,8 @@ public class StandardTypeLocator implements TypeLocator {
@@ -48,6 +51,8 @@ public class StandardTypeLocator implements TypeLocator {
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 }
@ -110,6 +115,21 @@ public class StandardTypeLocator implements TypeLocator {
@@ -110,6 +115,21 @@ public class StandardTypeLocator implements TypeLocator {
* /
@Override
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 {
return ClassUtils . forName ( typeName , this . classLoader ) ;
}
@ -125,7 +145,7 @@ public class StandardTypeLocator implements TypeLocator {
@@ -125,7 +145,7 @@ public class StandardTypeLocator implements TypeLocator {
// might be a different prefix
}
}
throw new SpelEvaluationException ( SpelMessage . TYPE_NOT_FOUND , typeName ) ;
return null ;
}
}