diff --git a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/types.adoc b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/types.adoc index df4d9cc3e0c..3d501f0de67 100644 --- a/framework-docs/modules/ROOT/pages/core/expressions/language-ref/types.adoc +++ b/framework-docs/modules/ROOT/pages/core/expressions/language-ref/types.adoc @@ -38,5 +38,15 @@ Kotlin:: ---- ====== +[NOTE] +==== +If your application or framework manages its own `EvaluationContext`, you may need to +manually configure a `StandardTypeLocator` with a specific `ClassLoader` to ensure that +the SpEL expression parser is able to reliably locate user types. + +For example, the `StandardBeanExpressionResolver` in the `spring-context` module +configures a `StandardTypeLocator` using the bean `ClassLoader` of the corresponding +`BeanFactory`. +==== diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java index 3886366b762..7219dface41 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardEvaluationContext.java @@ -40,12 +40,17 @@ import org.springframework.util.Assert; /** * A powerful and highly configurable {@link EvaluationContext} implementation. - * This context uses standard implementations of all applicable strategies, - * based on reflection to resolve properties, methods and fields. * - *
For a simpler builder-style context variant for data-binding purposes, + *
This context uses standard implementations of all applicable strategies, + * based on reflection to resolve properties, methods, and fields. Note, however, + * that you may need to manually configure a {@code StandardTypeLocator} with a + * specific {@link ClassLoader} to ensure that the SpEL expression parser is able + * to reliably locate user types. See {@link #setTypeLocator(TypeLocator)} for + * details. + * + *
For a simpler, builder-style context variant for data-binding purposes, * consider using {@link SimpleEvaluationContext} instead which allows for - * opting into several SpEL features as needed by specific evaluation cases. + * opting into several SpEL features as needed by specific use cases. * * @author Andy Clement * @author Juergen Hoeller @@ -183,11 +188,29 @@ public class StandardEvaluationContext implements EvaluationContext { return this.beanResolver; } + /** + * Set the {@link TypeLocator} to use to find types, either by short or + * fully-qualified name. + *
By default, a {@link StandardTypeLocator} will be used. + *
NOTE: Even if a {@code StandardTypeLocator} is + * sufficient, you may need to manually configure a {@code StandardTypeLocator} + * with a specific {@link ClassLoader} to ensure that the SpEL expression + * parser is able to reliably locate user types. + * @param typeLocator the {@code TypeLocator} to use + * @see StandardTypeLocator#StandardTypeLocator(ClassLoader) + * @see #getTypeLocator() + */ public void setTypeLocator(TypeLocator typeLocator) { Assert.notNull(typeLocator, "TypeLocator must not be null"); this.typeLocator = typeLocator; } + /** + * Get the configured {@link TypeLocator} that will be used to find types, + * either by short or fully-qualified name. + *
See {@link #setTypeLocator(TypeLocator)} for further details. + * @see #setTypeLocator(TypeLocator) + */ @Override public TypeLocator getTypeLocator() { if (this.typeLocator == null) { diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeLocator.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeLocator.java index aa6ada780b0..0e1d829b52b 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeLocator.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeLocator.java @@ -29,7 +29,8 @@ import org.springframework.util.ClassUtils; /** * A simple implementation of {@link TypeLocator} that uses the default - * {@link ClassLoader} or a supplied {@link ClassLoader} to locate types. + * {@link #StandardTypeLocator() ClassLoader} or a supplied + * {@link #StandardTypeLocator(ClassLoader) ClassLoader} to locate types. * *
Supports well-known packages, registered as * {@linkplain #registerImport(String) import prefixes}. If a type cannot be found, @@ -51,6 +52,9 @@ public class StandardTypeLocator implements TypeLocator { /** * Create a {@code StandardTypeLocator} for the default {@link ClassLoader} * (typically, the thread context {@code ClassLoader}). + *
Favor {@link #StandardTypeLocator(ClassLoader)} over this constructor + * in order to provide a specific {@link ClassLoader} that is able to reliably + * locate user types. * @see ClassUtils#getDefaultClassLoader() */ public StandardTypeLocator() { @@ -59,6 +63,9 @@ public class StandardTypeLocator implements TypeLocator { /** * Create a {@code StandardTypeLocator} for the given {@link ClassLoader}. + *
Favor this constructor over {@link #StandardTypeLocator()} in order + * to provide a specific {@link ClassLoader} that is able to reliably locate + * user types. * @param classLoader the {@code ClassLoader} to delegate to */ public StandardTypeLocator(@Nullable ClassLoader classLoader) {