Spring/Spring Core

[Spring] SpEL(Spring Expression Language)

TheWing 2020. 11. 5. 20:35

1. SpEL(Spring Expression Language)이란?

SpEL

  • Spring Expression Language는 SpEL로 많이 표기한다. Spring EL 이라고도 불린다.
  • Spring 3.0 부터 지원이 되었다.
  • 객체 그래프를 조회하거나 조작하는 기능을 제공한다
  • Unified EL과 비슷하지만, 메소드 호출을 지원하며, 문자열 템플릿 기능도 제공한다.
  • OGNL, MVEL, JBoss EL 등 자바에서 사용할 수 있는 여러 EL이 있지만 SpEL은
    모든 스프링 프로젝트 전반에 걸쳐 사용할 EL로 만들어졌다.

EL 참고

<c:if test="${sessionScope.cart.numberOfItems > 0}"> 
  ...
</c:if>
  • if test 안에 ${sessionScope.cart.numberOfItems > 0} JSP나 Thymeleaf처럼 이런 EL을 써본적이 있는 분들이 있을 것이다. 이것이 EL이다

2. 문법

  • #{"표현식"}
  • ${"property"}
  • 표현식은 프로퍼티를 가질 수 있지만, 프로퍼티는 표현식을 가지지 못한다.

    • EX) #{${my.data} + 1}
  • Reference 를 참고

3. 기능

  • Expression Language는 다음의 기능을 지원한다
    • 리터럴 표현식 (Literal Expression)
    • 불린과 관계형 오퍼레이터 (Boolean and Relational Operator)
    • 정규 표현식 (Regular Expression)
    • Class 표현식 (Class Expression)
    • 프로퍼티, 배열, 리스트, 맵에 대한 접근 (Access property, Array, List, Map)
    • 메서드 호출 (Method Invocation)
    • 관계형 오퍼레이터 (Relational Operator)
    • 할당 (Allocation)
    • 생성자 호출 (Calling Constructors)
    • 빈(Bean) 참조 (Bean References)
    • 배열 생성 (Array Contruction)
    • 인라인 리스트, 인라인 맵 (Inline List, Inline Map)
    • 삼항 연산자 (Ternary Operator)
    • 변수 (Variable)
    • 사용자 정의 함수 (User Defined Functions)
    • 컬렉션 투영 (Collection Projection)
    • 컬렉션 선택 (Collenction Selection
    • 템플릿화된 표현식 (Templated Expression)

4. 주로 사용되는 곳

  • @Value Annotation
  • @ConditionalOnExpression
  • Spring Security
    • Method Security, @PreAuthorize , @PostAuthorize, @PreFilter, @PostFilter
    • XML Intercepter URL Setting
    • 등등
  • Spring Data
    • @Query
  • Thymeleaf
  • 등등

5. @Value Annotation에서 사용 예제

1) SpEL 예제

  • 보통 @Value Annotation 에서 사용이 되는데 프로퍼티의 값을 가져올 때 많이 사용이 된다.
  • Bean 이 생성될때 @Value Annotation안에 사용한 값이 #{} 로 감싸져있으면 SpEL로 파싱해서 평가해서 결과 값을 변수에 할당해준다
@Component
public class AppRunner implements ApplicationRunner {
        @Value("#{ 2 + 2}")
        int value;

        @Value("#{'hello ' + 'world'}")
        String greeting;

        @Value("#{'TheWing '+ 'Tistory Blog'}")
        String TheWing;

        @Value("#{1 eq 1}")
        boolean trueOrFalse;

        @Override
        public void run(ApplicationArguments args) throws Exception {
            System.out.println("================");
            System.out.println("value = " + value);
            System.out.println("greeting = " + greeting);
            System.out.println("TheWing = " + TheWing);
            System.out.println("trueOrFalse = " + trueOrFalse);
        }
}
  • String은 리터럴 값이다.
  • 결과

================
value = 4
greeting = hello world
TheWing = TheWing Tistory Blog
trueOrFalse = true

2) Property

  • application.properties 에 아래와 같이 생성
application.properties

my.value = 100

@Component
public class AppRunner implements ApplicationRunner {
    @Value("${my.value}")
  int myValue;

  @Value("#{${my.value} eq 100}")
  boolean isMyValue100;
    @Override
    public void run(ApplicationArguments args) throws Exception {
        System.out.println("myValue = " + myValue);
      System.out.println("isMyValue100 = " + isMyValue100);
    }
}
  • 결과
myValue = 100
isMyValue100 = true

  • 표현식 안에는 프로퍼티를 사용할 수 있지만 프로퍼티 안에서는 사용하지 못한다

6. Expression 인터페이스를 사용한 SpEL 평가

  • ExpressionParser 인터페이스는 문자열 표현을 파싱하는 책임이 있다. parser를 생성한다
  • SpelExpressionParserExpressionParser 의 구현체이다. 표현식을 작성하고
  • Expression.getValue() 메소드로 파싱된 결과값을 Integer 래퍼클래스로 받을 수 있다.
ExpressionParser parser = new SpelExpressionParser();
Expression expression = parser.parseExpression("100 + 200");
Integer value = expression.getValue(Integer.class);
System.out.println(value);
  • 결과
300

References