Spring/스프링 프레임워크 핵심 원리

[Spring] #17. SpEL(스프링 Expression Language)

sujin7837 2020. 12. 24. 20:42
반응형

SpEL이란?

-객체 그래프를 조회하고 조작하는 기능을 제공합니다.

-스프링 3.0부터 지원합니다.

-Unified EL과 비슷하지만, 추가적으로 메소드 호출을 지원하고, 문자열 템플릿 기능도 제공합니다.

-스프링 핵심 기술단(core)뿐만 아니라, 스프링 프로젝트 전반에 걸쳐 널리 사용됩니다.

 

//AppRunner.java

@Component
public class AppRunner implements ApplicationRunner {
    @Value("#{1 + 1}")    //#{ }: 표현식을 이용하는 방법
    int value;

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

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

    @Value("hello")
    String hello;

    @Value("${my.value}")    //${ }: property를 참고하는 방법
    int myValue;
    //application properties 파일에 my.value=100을 추가하면 myValue에 100이 저장됩니다.

    @Value("#{${my.value} eq 100}")    //표현식 안에 property를 넣은 것
    int isMyValue100;

    @Value("#{sample.data}")    //sample이라는 빈의 data 값을 가져옴
    int sampleData;

    @Override
    public void run(ApplicationArguments args) throws Exceotion {
        System.out.println("================");
        System.out.println(value);
        System.out.println(greeting);
        System.out.println(trueOrFalse);
        System.out.println(myValue);
        System.out.println(isMyValue100);
        System.out.println(sampleData);    
    }
}

//ApplicationRunner라는 클래스를 구현하면 스프링 부트 애플리케이션이 실행된 다음 클래스 안의 코드가 바로 실행됩니다.
//"#{ }": { }안에  내용을 입력하여 표현식을 사용할 수 있습니다. 
//Component 빈이 만들어질 때, Value라는 어노테이션을 사용할 때 괄호 안의 값을 SpEL로 parsing해서 그 결과값을 파라미터에 넣어줍니다.
//표현식 안에는 property를 사용할 수 있으나, property 안에는 표현식을 사용할 수 없습니다.
//Sample.java
//Sample이라는 빈을 만듦

@Component
public class Sample {
    private int data=200;
    
    public int getData() {
        return data;
    }

    public int setData(int data) {
        this.data=data;
    }
}

 

실제로 SpEL이 쓰이는 곳

-@Value 어노테이션

-@ConditionalOnExpression 어노테이션 //선택적으로 빈을 등록하거나 빈 설정 파일을 읽어들일 때 사용할 수 있는 어노테이션으로, SpEL을 기반으로 선별적으로 빈을 등록할 수 있게 해줍니다.

-스프링 시큐리티: @PostAuthorize @PostFilter, @PreAuthorize, @PostAuthorize

-스프링 데이터: @Query 어노테이션

-Thymeleaf

SpEL 구성

-ExpressionParser parser=new SpelExpressionParser()

-StandardEvaluationContext context=new StandardEvaluationContext(bean)

-Expression expression=parser.parseExpression("SpEL 표현식")

-String value=expression.getvalue(context, String.class)

//AppRunner.java

@Component
public class AppRunner implements ApplicationRunner {
    @Value("#{1 + 1}")    
    int value;

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

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

    @Value("hello")
    String hello;

    @Value("${my.value}")    
    int myValue;

    @Value("#{${my.value} eq 100}")    
    int isMyValue100;

    @Value("#{sample.data}")   
    int sampleData;

    @Override
    public void run(ApplicationArguments args) throws Exceotion {
        System.out.println("================");
        System.out.println(value);
        System.out.println(greeting);
        System.out.println(trueOrFalse);
        System.out.println(myValue);
        System.out.println(isMyValue100);
        System.out.println(sampleData);    

        ExpressionParser parser=new SpelExpressionParser();
        parser.parseExpression(s: "2 + 100");    //괄호 안에 들어가는 것 자체가 expression 입니다.
        Integer value=expression.getValue(Integer.class);    //어떤 타입으로 값을 가져올 것인지 정함(integer로 가져온 예시), 이때 SpEL도 conversion 서비스를 사용합니다.(해당하는 타입으로 변환)
        System.out.println(value);
    }
}
반응형