아무거나

SpEL(Spring Expression Language) 본문

Java & Kotlin/Spring

SpEL(Spring Expression Language)

전봉근 2022. 10. 11. 14:56
반응형
  • SpEL(Spring Expression Language)
    • 정의
      • 런타임시 객체 그래프를 조회하고 조작하는 강력한 표현언어이다.
      • EL(Unified EL) 과 비슷하지만 추가적인 기능을 제공
      • OGNL, MVEL, JBOss EL 등 자바에서 사용할 수 있는 여러 EL이 있지만 SpEL은 모든 스프링 프로젝트 전반에 걸쳐서 사용 가능
      • 스프링 3.0부터 지원 가능
    • 기능
      • 리터럴 표현식 (Literal Expression)
      • Boolean 및 관계 연산자 (Boolean and Relational Operator)
      • 정규식 (Regular Expression)
      • 클래스 표현식 (Class Expression)
      • 속성, 배열, 목록, 맵 액세스 (Accessing Properties, arrays, lists, maps)
      • 메소드 호출 (Method Invocation)
      • 관계 연산자 (Relational Operator)
      • 할당 (Assignment)
      • 생성자 호출 (Calling Constructors)
      • 빈 참조 (Bean References)
      • 배열 구성 (Array Contruction)
      • 인라인 리스트/맵 (Inline List/Map)
      • 삼항 연산자 (Ternary Operator)
      • 변수 (Variables)
      • 사용자 정의 함수 (User defined functions)
      • 컬렉션 투영 (Collection Projection)
      • 컬렉션 선택 (Collection Selection)
      • 템플릿화된 표현식 (Templated Expression)
    • 문법
      • 문법 이 곳을 참고하면 여러가지 문법을 활용할 수 있다.
      • 몇 가지 문법들 정도만 알아보자.
        • @Value 애노테이션에서 사용 (Bean 이 생성될 때 @Value() 안의 값이 #{} 표기로 감싸져있으면 SpEL 로 파싱 후 연산하여 결과값을 변수에 할당)
          // 결과: 3
          @Value("#{2+1}")
          private int addValue;
          
          // 결과: bkjeon
          @Value("#{'bk' + 'jeon'}")
          private String bkjeonValue;
          
          // 결과: false
          @Value("#{3 eq 5}")
          private boolean booleanValue;
          
          // 결과: literal value
          @Value("literal value")
          private String literalValue;
          
        • Property (SpEL 은 Property 를 가질 수 있지만 반대로는 불가능하다.)
          [application.yml]
          spel:
            value: 100
          
          [example code]
          // 결과: true
          @Value("#{'${spel.value}' eq '100'}")
          private boolean booleanValue;
          
        • Bean Reference(빈 참조) 방법 (#{빈id.프로퍼티} 형식으로 참조)
          import org.springframework.stereotype.Component;
          
          @Component
          @Getter
          public class SpELSample {
          
              private int testValue = 100;
          
          }
          
          ...
          // 결과: 100
          @Value("#{spELSample.testValue}")
          private int testValue;
          
        • Expression 사용한 SpEL 파싱
          // ExpressionParser의 구현체 SpelExpressionParser로 SpEL의 내용을 파싱(Parsing) 하고
          // Expression의 getValue() 메서드를 이용해 파싱된 결과값을 Object 타입으로 얻을 수 있다.
          ExpressionParser parser = new SpelExpressionParser();
          Expression expression = parser.parseExpression("2+1");
          
          // getValue() 호출 시 Class 정보를 넘기면 자동으로 타입 캐스팅이 가능함
          Object value = expression.getValue(Integer.class);
          log.info("expression: {}", value);        
          
        • EvaluationContext를 사용한 SpEL 파싱 (StandardEvaluationContext를 사용하는 경우 생성 비용이 발생하지만 필드에 대해 캐싱하기 때문에 반복적으로 사용하면 표현식 파싱이 더 빠르다는 장점이 있다.)
          import lombok.AllArgsConstructor;
          import lombok.Getter;
          
          @Getter
          @AllArgsConstructor
          public class SpELSample2 {
          
              private String name;
              private String region;
          
          }        
          
          // name, nationality 를 파라미터로 갖는 생성자
          SpELSample2 spELSample2 = new SpELSample2("bkjeon", "Seoul");
          
          ExpressionParser parser = new SpelExpressionParser();
          Expression exp = parser.parseExpression("name"); // name 프로퍼티
          
          // Context에 tesla객체를 넣어준다.
          EvaluationContext context = new StandardEvaluationContext(spELSample2);
          String name1 = (String) exp.getValue(context); // name = "bkjeon"
          log.info("name1: {}", name1);	// bkjeon
          
          // getValue 메서드 호출 시 StandardEvaluationContext를 사용하지 않고 객체를 직접 지정
          String name2 = (String) exp.getValue(spELSample2);
          log.info("name2: {}", name2);	// bkjeon        
          

 

참고

- https://devwithpug.github.io/spring/spring-spel/

https://docs.spring.io/spring-framework/docs/3.0.x/reference/expressions.html

https://velog.io/@probsno/

반응형
Comments