Я столкнулся с некоторыми проблемами с производительностью, и после небольшого отслеживания я обнаружил, что это происходит потому, что компилятор SpEL отказывается компилировать выражение, если все это не выполнялось нормально (эта часть ожидается). В моем случае это происходило из-за логического оператора.
Я заметил, что в случае логического или ( || )
- когда вы используете логический оператор ( || ), разделяющий два выражения в SpEL.
- Первая половина выражения в большинстве случаев верна; вторая половина не выполняется.
- Это приводит к тому, что компилятору не хватает информации о второй половине выражения для его компиляции.
У меня есть минимальный пример такого поведения.
Код: Выделить всё
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
import org.springframework.expression.Expression;
import org.springframework.expression.ExpressionParser;
import org.springframework.expression.spel.SpelCompilerMode;
import org.springframework.expression.spel.SpelParserConfiguration;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
import org.springframework.scheduling.annotation.EnableAsync;
@EnableAsync
@Configuration
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
ExpressionParser parser = new SpelExpressionParser(
new SpelParserConfiguration(SpelCompilerMode.IMMEDIATE, Main.class.getClassLoader())
);
Expression expression = parser.parseExpression("(#var1) || (#var2)");
StandardEvaluationContext context = new StandardEvaluationContext();
for (int i = 0; i < 10000; i++) {
context.setVariable("var1", true);
context.setVariable("var2", false);
expression.getValue(context, Object.class);
}
System.out.println("End");
}
}
Код: Выделить всё
logging.level.org.springframework.expression=TRACE
Код: Выделить всё
2025-11-26T12:58:18.891+05:30 DEBUG 20156 --- [ main] o.s.e.spel.standard.SpelCompiler : SpEL: unable to compile (#var1 or #var2)
2025-11-26T12:58:18.891+05:30 DEBUG 20156 --- [ main] o.s.e.spel.standard.SpelCompiler : SpEL: unable to compile (#var1 or #var2)
2025-11-26T12:58:18.891+05:30 DEBUG 20156 --- [ main] o.s.e.spel.standard.SpelCompiler : SpEL: unable to compile (#var1 or #var2)
2025-11-26T12:58:18.891+05:30 DEBUG 20156 --- [ main] o.s.e.spel.standard.SpelCompiler : SpEL: unable to compile (#var1 or #var2)
2025-11-26T12:58:18.891+05:30 DEBUG 20156 --- [ main] o.s.e.spel.standard.SpelCompiler : SpEL: unable to compile (#var1 or #var2)
2025-11-26T12:58:18.891+05:30 DEBUG 20156 --- [ main] o.s.e.spel.standard.SpelCompiler : SpEL: unable to compile (#var1 or #var2)
2025-11-26T12:58:18.891+05:30 DEBUG 20156 --- [ main] o.s.e.spel.standard.SpelCompiler : SpEL: unable to compile (#var1 or #var2)
End
Существуют ли способы написать выражения так, чтобы вычислялись обе половины и, таким образом, выражение компилировалось? Или какие-нибудь другие обходные пути?
Подробнее здесь: https://stackoverflow.com/questions/798 ... spel-expre
Мобильная версия