개발/Java & Kotlin

[Spring] Spring에서 @Value 어노테이션 사용 시 주의할 점 정리

devhooney 2025. 7. 11. 08:21
728x90

스프링에서 설정값 주입할 때 가장 직관적인 방법 중 하나가 @Value다.
application.properties나 application.yml에 있는 값을 ${}로 꺼내서 바로 필드에 넣을 수 있어서 간단하고 편하기 때문.

근데 실무에서 무심코 쓰다가 에러를 겪거나, 나중에 유지보수하다가 “이게 왜 이렇게 되어 있지?” 싶을 때가 은근 많다.
그래서 이번엔 @Value 어노테이션 쓸 때 주의해야 할 점들만 쏙쏙 뽑아서 정리해봤다.

 

 

 


 

 

 

✅ 기본 사용법부터 간단히 보자

@Value("${myapp.name}")
private String appName;

 

application.properties에 아래처럼 설정해두면,

myapp.name=MySpringApp

 

Spring이 자동으로 appName에 "MySpringApp" 값을 넣어준다.
여기까지는 딱히 문제될 게 없어 보이지만…

 

 


 

⚠️ 실무에서 자주 놓치는 주의사항들
1. ${}랑 #{} 헷갈리지 말자
@Value는 SpEL(Spring Expression Language)도 같이 지원한다.
그래서 ${}는 프로퍼티 값 주입이고, #{}는 표현식 평가다.

@Value("${myapp.name}") // 설정 값
private String name;

@Value("#{1 + 2}") // 표현식
private int sum; // 3

 

이거 헷갈리면 런타임에 예외 난다.
예를 들어 ${1 + 2} 이런 식으로 쓰면 Could not resolve placeholder 에러 뜬다.

 

 

 


 

 

2. static 필드엔 주입 안 된다

@Value("${myapp.name}")
private static String appName; // ❌ 안 됨

 

스프링은 인스턴스를 생성한 뒤에 의존성 주입을 하는 구조라서, static 필드엔 값을 넣어줄 수가 없다.
이거 모르고 쓰면 null 나오거나 아예 주입이 안 된다.

만약 꼭 static 필드에서 설정 값을 써야 한다면, @PostConstruct로 우회하거나 setter 메서드 통해서 따로 할당해줘야 한다.

 

 

 


 

3. 컴포넌트 스캔 안 되는 클래스에선 작동안 함
@Value는 스프링 빈(즉, 컴포넌트로 등록된 클래스)에서만 동작한다.
그냥 POJO에다 @Value 붙여봤자 아무 일도 안 일어난다.

public class MyUtil {
    @Value("${myapp.name}") // ❌ 주입 안 됨
    private String name;
}

 

이럴 땐 해당 클래스에 @Component를 붙이거나, 생성자 통해 값을 넘겨주는 방식으로 가야 한다.

 

 


 

 

 

 

 

 

728x90

 

 

 

 

4. 타입 변환 문제 조심
예를 들어 숫자 타입으로 설정값을 주입할 땐, 문자열로 들어오는 값을 스프링이 내부적으로 변환해주는 건데, 포맷이 안 맞으면 예외가 터진다.

@Value("${myapp.timeout}")
private int timeout; // application.properties에서 값이 숫자가 아니면 예외

 

값이 "10s" 이런 식이면 당연히 NumberFormatException 뜬다.
정수, 불리언 등 타입에 민감한 필드에는 형식을 꼭 확인하고 넣어줘야 한다.

 

 


 

5. 설정 값 누락 시 앱이 터질 수 있음
@Value("${some.key}")로 값을 주입할 때 해당 키가 설정돼 있지 않으면 IllegalArgumentException이 발생한다.
그래서 꼭 필요한 값이 아니라면 기본값을 같이 넣는 게 좋다.

@Value("${some.key:defaultValue}")
private String someKey;



이렇게 쓰면 설정값이 없을 경우 "defaultValue"가 자동으로 들어간다.
안전하게 코딩하려면 기본값 넣는 습관 들이는 게 좋다.

 


 

@Value vs @ConfigurationProperties
설정값이 많아지거나, 계층적인 구조를 가진다면 @ConfigurationProperties가 훨씬 낫다.

예:

@Value("${myapp.name}")
private String name;

@Value("${myapp.version}")
private String version;

 

이렇게 하나씩 주입하는 것보다,

 

@ConfigurationProperties(prefix = "myapp")
@Component
public class MyAppProps {
    private String name;
    private String version;
}

 

이렇게 한 번에 묶어서 관리하는 게 유지보수나 테스트에도 유리하다.
특히 YML 구조가 복잡할수록 @ConfigurationProperties가 깔끔하다.

 

 

 

 

 

 

728x90