Spring Boot 설정값 바인딩 정리: @Value vs @ConfigurationProperties

2025. 5. 24. 16:41·TIL (Today I Learned)

application.yml, application.properties 등의 설정 파일로부터 값을 읽어와서 스프링 빈에 주입하기 위해서
@Value와 @ConfigurationProperties를 사용할 수 있다.

 

@Value vs @ConfigurationProperties

application.yml 예시 - aws 환경 설정 값

  @Value @ConfigurationProperties
목적 단일 속성 주입
`@Value("${cloud.aws.s3.bucket}")`
예: 환경변수 `AWS_S3_BUCKET` 값 하나
다수의 속성 주입
`@ConfigurationProperties(prefix = "cloud.aws.s3")`
예: s3 아래의 환경변수들 (`AWS_S3_BUCKET`, `AWS_S3_PRESIGNED_EXPIRATION`)
주입 방식 필드만 주입 가능 (`final` 불가능) 생성자 주입 가능 (`final` 사용 가능)
이름 매핑 직접 지정 Spring Boot가 kebab-case → camelCase 자동으로 처리
예: `presigned-url-expiration` → `presignedUrlExpiration`

 

@ConfigurationProperties 사용 방식

application.yml 예시 - kakao 환경 설정 값

 

바인딩 방법

⚠️ Setter가 없거나 필드 접근이 불가능할 경우 바인딩 실패

Error starting ApplicationContext. To display the condition evaluation report re-run your application with 'debug' enabled.
2025-04-16T21:47:06.550+09:00 ERROR 4516 --- [table-now] [ main] o.s.b.d.LoggingFailureAnalysisReporter :
--- APPLICATION FAILED TO START ---
Description:
Failed to bind properties under 'oauth.kakao' to
org.example.tablenow.domain.auth.oAuth.config.KakaoOAuthProperties:
Property: oauth.kakao.admin-key
Value: "${KAKAO_ADMIN_KEY}"
Origin: class path resource [application.yml] - 78:16
Reason: java.lang.IllegalStateException: No setter found for property: admin-key
Action: Update your application's configuration

→ @ConfigurationProperties를 사용할 때는 바인딩을 위해 setter 방식 또는 생성자 방식 중 하나를 사용해야 한다.

 

1. `@Setter` 방식

@Getter
@Setter
@ConfigurationProperties(prefix = "oauth.kakao")
public class KakaoOAuthProperties {
    private String adminKey;
    private String unlinkUri;
}
  • 기본 생성자와 setter를 통해 바인딩

 

2. 생성자 바인딩 방식 (Spring Boot 3.x 기준)

@Getter
@ConfigurationProperties(prefix = "oauth.kakao")
public class KakaoOAuthProperties {

    private final String adminKey;
    private final String unlinkUri;

    public KakaoOAuthProperties(String adminKey, String unlinkUri) {
        this.adminKey = adminKey;
        this.unlinkUri = unlinkUri;
    }

    public String getAdminKey() {
        return adminKey;
    }

    public String getUnlinkUri() {
        return unlinkUri;
    }
}
  • Spring Boot 3.0 이상에서는 @ConstructorBinding 없이도 생성자가 하나뿐이라면 자동으로 생성자 바인딩이 적용됨
    • 공식 문서 내용 중 - there is no need to use @ConstructorBinding.
  • `final` 필드를 사용할 수 있어 불변 객체로 관리 가능
더보기

참고: Spring Boot 2.x에서 생성자 바인딩 방법: `@ConstructorBinding` 방식

Spring Boot 2.2 이상에서는 `@ConstructorBinding` 방식으로 바인딩 가능

@Getter
@ConfigurationProperties(prefix = "oauth.kakao")
@ConstructorBinding
public class KakaoOAuthProperties { ... }
오류 - Spring Boot 3.x에서 @ConstructorBinding을 사용할 경우

 

등록 방법

@ConfigurationProperties를 사용한 클래스는 스프링 컨테이너에 등록되어야 바인딩이 적용 가능

 

1. `@Component` 직접 사용

@Getter
@Setter
@Component
@ConfigurationProperties(prefix = "oauth.kakao")
public class KakaoOAuthProperties {
    private String adminKey;
    private String unlinkUri;
}
  • @Component로 직접 빈 등록 → 바로 다른 서비스에 주입 가능
    • `@Component`: 스프링 빈으로 등록
    • `@ConfigurationProperties`: 외부 설정을 바인딩
    • → 두 역할이 한 클래스에 동시에 주어져, 설정 클래스가 빈 등록과 바인딩 책임을 모두 지게 됨
    • → 단일 책임 원칙(SRP) 위반 가능
  • 생성자 바인딩 방식과 어울리지 않음
    • @Component 방식은 기본적으로 기본 생성자 + setter 주입을 전제로 동작하기 때문
    • @Component를 붙이면 Spring이 내부적으로 빈 생성 시 기본 생성자를 호출한 뒤, setter로 값을 주입
      → final 필드는 주입 불가 → 불변 객체 설계 불가

 

2. `@ConfigurationPropertiesScan` 또는 `@EnableConfigurationProperties` 사용

  • 생성자 바인딩 방식에 적절함 → 불변 객체 사용 가능
  • Spring 공식 문서에서 권장하는 방법
  • 설정 클래스와 빈 등록 책임이 분리됨 → SRP(단일 책임 원칙) 만족
  • `@ConfigurationPropertiesScan`
    • `@ConfigurationProperties` 클래스 자동 등록
@ConfigurationPropertiesScan
@SpringBootApplication
public class TableNowApplication { ... }
  •  `@EnableConfigurationProperties`
    • 명시적으로 클래스를 지정해 등록
@EnableConfigurationProperties(KakaoOAuthProperties.class)
@SpringBootApplication
public class TableNowApplication { ... }

 

📝 결론

  • 설정값이 많은 경우에는 @ConfigurationProperties를 사용해 구조화된 방식으로 관리
  • @ConfigurationProperties를 사용 할 때, 바인딩을 위해서 다음 중 하나를 사용해야 한다:
    • @Setter 방식 (기본 생성자 + setter)
    • 생성자 바인딩 방식 (final 필드 + 생성자 → 불변 객체 설정)
  • Spring Boot 3.x 이상에서는 @ConstructorBinding 없이도 생성자 하나만 있으면 자동 바인딩 됨
  • 설정 값을 불변 객체로 사용할 경우에는 생성자 바인딩 방식 사용이 적합
  • @ConfigurationPropertiesScan로 등록해서 사용

✔️ 설정값이 많고 구조화가 필요한 경우, @ConfigurationProperties + 생성자 바인딩 방식을 추천합니다.

 

공식문서 참고: https://docs.spring.io/spring-boot/reference/features/external-config.html#features.external-config.typesafe-configuration-properties

 

Externalized Configuration :: Spring Boot

The RandomValuePropertySource is useful for injecting random values (for example, into secrets or test cases). It can produce integers, longs, uuids, or strings, as shown in the following example: my.secret=${random.value} my.number=${random.int} my.bignum

docs.spring.io

 

저작자표시 비영리 변경금지 (새창열림)

'TIL (Today I Learned)' 카테고리의 다른 글

Synchronous 🆚 Asynchronous | RabbitMQ 기반 비동기 처리 구조  (2) 2025.06.05
JWT 인증 기반 WebSocket 연결 실패, 원인과 해결법  (2) 2025.06.05
동시성 제어는 어떻게 할까❓  (0) 2025.03.26
Windows 개발 환경에서 AWS 활용 과제 | Spring Boot v3.3.3 & Gradle 8.12  (0) 2025.03.21
SPRING PLUS 과제 | 회고와 트러블슈팅⛹️‍♀️  (0) 2025.03.21
'TIL (Today I Learned)' 카테고리의 다른 글
  • Synchronous 🆚 Asynchronous | RabbitMQ 기반 비동기 처리 구조
  • JWT 인증 기반 WebSocket 연결 실패, 원인과 해결법
  • 동시성 제어는 어떻게 할까❓
  • Windows 개발 환경에서 AWS 활용 과제 | Spring Boot v3.3.3 & Gradle 8.12
기만나🐸
기만나🐸
공부한 내용을 기록합시다 🔥🔥🔥
  • 기만나🐸
    기만나의 공부 기록 🤓
    기만나🐸
  • 전체
    오늘
    어제
    • ALL (147)
      • TIL (Today I Learned) (56)
      • Dev Projects (15)
      • Algorithm Solving (67)
        • Java (52)
        • SQL (15)
      • Certifications (8)
        • 정보처리기사 실기 (8)
  • 인기 글

  • 태그

    javascript
    greedy
    시뮬레이션
    완전탐색
    Subquery
    dp
    프로그래머스
    Google Fonts
    BFS
    GROUP BY
    그리디
    jwt
    CSS
    DFS
    join
    sql
    Firebase
    bootstrap
    jpa
    mysql
    websocket
    백준
    HTML
    백트래킹
    자료구조
    jQuery
    다이나믹프로그래밍
    java
    programmers
    BOJ
  • 최근 글

  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.3
기만나🐸
Spring Boot 설정값 바인딩 정리: @Value vs @ConfigurationProperties
상단으로

티스토리툴바