Принудительно выполнить полную оценку выражения или отключить логику короткого замыкания в выражениях SpEL.JAVA

Программисты JAVA общаются здесь
Ответить
Anonymous
 Принудительно выполнить полную оценку выражения или отключить логику короткого замыкания в выражениях SpEL.

Сообщение Anonymous »

Я работаю над приложением, в котором оно динамически генерирует и выполняет некоторые выражения Spring Expression Language (SpEL).
Я столкнулся с некоторыми проблемами с производительностью, и после небольшого отслеживания я обнаружил, что это происходит потому, что компилятор 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

Но если var1 имеет значение false или иногда false, выражение компилируется.
Существуют ли способы написать выражения так, чтобы вычислялись обе половины и, таким образом, выражение компилировалось? Или есть другие обходные пути?
Заранее спасибо.

Подробнее здесь: https://stackoverflow.com/questions/798 ... spel-expre
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «JAVA»