diff --git a/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java b/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java index c2a0235d1972..b58795014b98 100644 --- a/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java +++ b/spring-context/src/main/java/org/springframework/context/expression/StandardBeanExpressionResolver.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2020 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -24,6 +24,7 @@ import org.springframework.beans.factory.config.BeanExpressionContext; import org.springframework.beans.factory.config.BeanExpressionResolver; import org.springframework.core.convert.ConversionService; +import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.expression.Expression; import org.springframework.expression.ExpressionParser; import org.springframework.expression.ParserContext; @@ -156,10 +157,10 @@ public Object evaluate(@Nullable String value, BeanExpressionContext evalContext sec.addPropertyAccessor(new EnvironmentAccessor()); sec.setBeanResolver(new BeanFactoryResolver(evalContext.getBeanFactory())); sec.setTypeLocator(new StandardTypeLocator(evalContext.getBeanFactory().getBeanClassLoader())); - ConversionService conversionService = evalContext.getBeanFactory().getConversionService(); - if (conversionService != null) { - sec.setTypeConverter(new StandardTypeConverter(conversionService)); - } + sec.setTypeConverter(new StandardTypeConverter(() -> { + ConversionService cs = evalContext.getBeanFactory().getConversionService(); + return (cs != null ? cs : DefaultConversionService.getSharedInstance()); + })); customizeEvaluationContext(sec); this.evaluationCache.put(evalContext, sec); } diff --git a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java index 8d1a25028874..eeb1c09397db 100644 --- a/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java +++ b/spring-expression/src/main/java/org/springframework/expression/spel/support/StandardTypeConverter.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2021 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,6 +16,8 @@ package org.springframework.expression.spel.support; +import java.util.function.Supplier; + import org.springframework.core.convert.ConversionException; import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.TypeDescriptor; @@ -37,7 +39,7 @@ */ public class StandardTypeConverter implements TypeConverter { - private final ConversionService conversionService; + private final Supplier conversionService; /** @@ -45,7 +47,7 @@ public class StandardTypeConverter implements TypeConverter { * @see DefaultConversionService#getSharedInstance() */ public StandardTypeConverter() { - this.conversionService = DefaultConversionService.getSharedInstance(); + this.conversionService = DefaultConversionService::getSharedInstance; } /** @@ -54,20 +56,30 @@ public StandardTypeConverter() { */ public StandardTypeConverter(ConversionService conversionService) { Assert.notNull(conversionService, "ConversionService must not be null"); + this.conversionService = () -> conversionService; + } + + /** + * Create a StandardTypeConverter for the given ConversionService. + * @param conversionService a Supplier for the ConversionService to delegate to + * @since 5.3.11 + */ + public StandardTypeConverter(Supplier conversionService) { + Assert.notNull(conversionService, "Supplier must not be null"); this.conversionService = conversionService; } @Override public boolean canConvert(@Nullable TypeDescriptor sourceType, TypeDescriptor targetType) { - return this.conversionService.canConvert(sourceType, targetType); + return this.conversionService.get().canConvert(sourceType, targetType); } @Override @Nullable public Object convertValue(@Nullable Object value, @Nullable TypeDescriptor sourceType, TypeDescriptor targetType) { try { - return this.conversionService.convert(value, sourceType, targetType); + return this.conversionService.get().convert(value, sourceType, targetType); } catch (ConversionException ex) { throw new SpelEvaluationException(ex, SpelMessage.TYPE_CONVERSION_ERROR,