Принудительно выполнить полную оценку выражения или отключить логику короткого замыкания в выражениях 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»