SpEL 은 사칙연산, 논리연산, 관계연산 사람의 표현식(중위 표현식)을 쉽게 평가할수가 있다.
+ - * /& | !> < == != in다음과 같이 괄호가 포함된 복잡한 표현도 가능하다.
Expression expression = parser.parseExpression("(#a or #b) and (!#c and !#d)");
코드 예시는 다음과 같다.
@Test
void shouldEvaluation_withSpel() {
// Evaluator 빈 생성 // 각각은 eval(ctx, factors) 메세지 구현 필요
Map<String, Evaluator> factory = Map.of(
"time", new TimeRangeEvaluator(),
"threashhold", new ThreashholdEvaluator(),
"text", new TextContainsEvaluator()
);
// 현재 컨텍스트. 조회를 해서 넣든, 도메인서비스를 넣든, 런타임에 평가할수 있도록 현재의 컨텍스트를 전달하는게 목표
CurrentContext ctx = new CurrentContext(12, 10, "hello world");
// SpEL 표현식 파싱 및 표현식
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext();
context.setVariable("a", factory.get("time").eval(ctx, 1, 23)); // 시간이 1~23시 사이
context.setVariable("b", factory.get("threashhold").eval(ctx, 5)); // 카운트가 5를 초과
context.setVariable("c", factory.get("text").eval(ctx, "제목1")); // title에 제목1 포함
context.setVariable("d", factory.get("text").eval(ctx, "제목2")); // title에 제목2 포함
Expression expression = parser.parseExpression("(#a or #b) and (!#c and !#d)");
// 표현식 평가
assertThat(expression.getValue(context, Boolean.class)).isTrue();
}
클라이언트로 전달받는 json 예시는 다음과 같다.
"evaluators" :
[
{
"var" : "a",
"type" : "timeRange",
"factor" : [0, 17]
},
{
"var" : "b",
"type" : "threashhold",
"factor" : [10]
}
]
"expression" : "(#a or #b) and (!#c and !#d)"