SpEL을 이용한 연산

Bonjugi·2024년 2월 18일

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 구문

클라이언트로 전달받는 json 예시는 다음과 같다.

"evaluators" :
[
  {
	"var" : "a",
    "type" : "timeRange",
    "factor" : [0, 17]
  },
  {
    "var" : "b",
    "type" : "threashhold",
    "factor" : [10]
  }
]
"expression" : "(#a or #b) and (!#c and !#d)"

0개의 댓글