Use Map#computeIfAbsent in SpEL support classes

Closes gh-32385
This commit is contained in:
Sam Brannen 2024-03-07 13:54:59 +01:00
parent dcbc2ef134
commit ac1176af53
2 changed files with 22 additions and 28 deletions

View File

@ -84,12 +84,7 @@ public abstract class CachedExpressionEvaluator {
AnnotatedElementKey elementKey, String expression) { AnnotatedElementKey elementKey, String expression) {
ExpressionKey expressionKey = createKey(elementKey, expression); ExpressionKey expressionKey = createKey(elementKey, expression);
Expression expr = cache.get(expressionKey); return cache.computeIfAbsent(expressionKey, key -> parseExpression(expression));
if (expr == null) {
expr = parseExpression(expression);
cache.put(expressionKey, expr);
}
return expr;
} }
/** /**

View File

@ -23,9 +23,11 @@ import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanExpressionException; import org.springframework.beans.factory.BeanExpressionException;
import org.springframework.beans.factory.config.BeanExpressionContext; import org.springframework.beans.factory.config.BeanExpressionContext;
import org.springframework.beans.factory.config.BeanExpressionResolver; import org.springframework.beans.factory.config.BeanExpressionResolver;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.core.SpringProperties; import org.springframework.core.SpringProperties;
import org.springframework.core.convert.ConversionService; import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.support.DefaultConversionService; import org.springframework.core.convert.support.DefaultConversionService;
import org.springframework.expression.EvaluationContext;
import org.springframework.expression.Expression; import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser; import org.springframework.expression.ExpressionParser;
import org.springframework.expression.ParserContext; import org.springframework.expression.ParserContext;
@ -159,28 +161,25 @@ public class StandardBeanExpressionResolver implements BeanExpressionResolver {
return value; return value;
} }
try { try {
Expression expr = this.expressionCache.get(value); Expression expr = this.expressionCache.computeIfAbsent(value, expression ->
if (expr == null) { this.expressionParser.parseExpression(expression, this.beanExpressionParserContext));
expr = this.expressionParser.parseExpression(value, this.beanExpressionParserContext); EvaluationContext evalContext = this.evaluationCache.computeIfAbsent(beanExpressionContext, bec -> {
this.expressionCache.put(value, expr); ConfigurableBeanFactory beanFactory = bec.getBeanFactory();
} StandardEvaluationContext sec = new StandardEvaluationContext(bec);
StandardEvaluationContext sec = this.evaluationCache.get(beanExpressionContext);
if (sec == null) {
sec = new StandardEvaluationContext(beanExpressionContext);
sec.addPropertyAccessor(new BeanExpressionContextAccessor()); sec.addPropertyAccessor(new BeanExpressionContextAccessor());
sec.addPropertyAccessor(new BeanFactoryAccessor()); sec.addPropertyAccessor(new BeanFactoryAccessor());
sec.addPropertyAccessor(new MapAccessor()); sec.addPropertyAccessor(new MapAccessor());
sec.addPropertyAccessor(new EnvironmentAccessor()); sec.addPropertyAccessor(new EnvironmentAccessor());
sec.setBeanResolver(new BeanFactoryResolver(beanExpressionContext.getBeanFactory())); sec.setBeanResolver(new BeanFactoryResolver(beanFactory));
sec.setTypeLocator(new StandardTypeLocator(beanExpressionContext.getBeanFactory().getBeanClassLoader())); sec.setTypeLocator(new StandardTypeLocator(beanFactory.getBeanClassLoader()));
sec.setTypeConverter(new StandardTypeConverter(() -> { sec.setTypeConverter(new StandardTypeConverter(() -> {
ConversionService cs = beanExpressionContext.getBeanFactory().getConversionService(); ConversionService cs = beanFactory.getConversionService();
return (cs != null ? cs : DefaultConversionService.getSharedInstance()); return (cs != null ? cs : DefaultConversionService.getSharedInstance());
})); }));
customizeEvaluationContext(sec); customizeEvaluationContext(sec);
this.evaluationCache.put(beanExpressionContext, sec); return sec;
} });
return expr.getValue(sec); return expr.getValue(evalContext);
} }
catch (Throwable ex) { catch (Throwable ex) {
throw new BeanExpressionException("Expression parsing failed", ex); throw new BeanExpressionException("Expression parsing failed", ex);