@Value 애노테이션의 기능과 역할 및 사용법

개요

애노테이션이 필드나 메서드(혹은 생성자)의 파라미터 수준에서 표현식 기반으로 값을 주입해주는 애노테이션입니다. 일반적으로 SpEL(Spring Expression Language)(ex: #{properties.myProp})이나 스타일 속성 자리표시자로 값을 주입할 수 있습니다(ex: ${catsbi.me.prop})

이 애노테이션을 처리하는 곳은 BeanPostProcessor 인터페이스의 구현체에서 처리됩니다.

왜 설정 값을 분리하는가?(기능과 역할)

사용법

@Component
@Data
public class ConstantsForSpEL {
    private String name = "catsbi";
    private String email = "[email protected]";
}
@Service
@Getter
public class TestProvider {

    @Value("#{constantsForSpEL.name}")
    private String name;

    @Value("#{constantsForSpEL.email}")
    private String email;

    @Value("${jwt.secret}")
    private String secret;
}
@SpringBootTest
class TestProviderTest {

    @Autowired
    private TestProvider testProvider;

    @Test
    void injectValueTest() {
        assertThat(testProvider.getEmail()).isEqualTo("[email protected]");
        assertThat(testProvider.getName()).isEqualTo("catsbi");
				assertThat(testProvider.getSecret()).isEqualTo("12345678901234567890123456789010");
    }

}

프로퍼티 치환자 방식보단 능동적인 SpEL을 사용하자.

기존에 익숙한 방식은 ${...} 방식의 프로퍼티 치환 방식입니다. 하지만 해당 방식은 오타를 작성했을 경우 에러 검증을 할 수 없기에 오타에 취약하다. 반면, SpEl 방식의 주입 방식은 프로퍼티 뿐 아니라 다른 객체에도 접근하기 쉽고, 메서드 및 연산까지 지원하기에 유연한 사용이 가능하다.

예를들어 기존에 사용했던 @Value("${jwt.secret}") 을 보면 프로퍼티에서 jwt.secret 프로퍼티를 찾아서 주입해준다. 하지만 만약 jwtt.secrettt라고 오타를 작성하면 컴파일단계에서 이를 찾을 수 없고 해당 프로퍼티를 찾을 수 없기에 제대로 값을 주입받지 못한다. 여기서 SpEL을 사용하면 다음과 같이 사용할 수 있다.

@Value("#{environment['jwt.secrett'] == null " + 
					"? '기본 시크릿 정보'" +
					": environment['jwt.secrett']}")
private String secret;

이렇게 작성을 한다면 만약 프로퍼티에서 해당 내용을 찾지못한다 하더라도 기본 시크릿 정보를 찾을 수 있기에 에러에서 좀 더 안전하고 테스트에 용이하다.

참고