@ConfigurationProperties

코딩냥이·2024년 9월 10일

Annotation

목록 보기
13/34

@ConfigurationProperties

@ConfigurationProperties는 스프링 부트에서 제공하는 어노테이션으로, 외부 설정(예: properties 파일, YAML 파일, 환경 변수 등)을 자바 객체에 바인딩할 때 사용됩니다.

기능

  • 외부 설정을 타입 안전한 방식으로 자바 POJO에 바인딩합니다.
  • 계층적 프로퍼티 구조를 지원합니다.
  • 유효성 검사(validation)를 지원합니다.
  • 메타데이터 생성을 통해 IDE 지원을 향상시킵니다.

사용 방법

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private String name;
    private String description;
    private int version;

    // getters and setters
}

그리고 application.properties 또는 application.yml 파일에서:

app.name=MyApp
app.description=This is my application
app.version=1

주요 특징

  1. prefix 지정: 관련 프로퍼티들을 그룹화하여 관리할 수 있습니다.
  2. 타입 안전성: 프로퍼티 값을 자동으로 적절한 타입으로 변환합니다.
  3. 중첩 클래스 지원: 복잡한 구조의 프로퍼티도 쉽게 매핑할 수 있습니다.
  4. 컬렉션 지원: List, Map 등의 컬렉션 타입도 지원합니다.
  5. 유효성 검사: JSR-303 (@Validated) 을 통한 유효성 검사를 지원합니다.

@ConfigurationProperties vs @Value

@ConfigurationProperties는 여러 관련 프로퍼티를 하나의 클래스로 바인딩할 때 유용합니다. 반면 @Value는 개별 프로퍼티를 주입할 때 사용됩니다.

// @ConfigurationProperties 사용
@Component
@ConfigurationProperties(prefix = "mail")
public class MailProperties {
    private String host;
    private int port;
    private String username;
    private String password;

    // getters and setters
}

// @Value 사용
@Component
public class MailConfig {
    @Value("${mail.host}")
    private String host;

    @Value("${mail.port}")
    private int port;

    // ...
}

복잡한 구조 매핑

중첩 클래스를 사용하여 복잡한 프로퍼티 구조를 매핑할 수 있습니다:

@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private String name;
    private Security security = new Security();

    public static class Security {
        private String username;
        private String password;
        private List<String> roles = new ArrayList<>();

        // getters and setters
    }

    // getters and setters
}

이는 다음과 같은 YAML 설정과 매핑됩니다:

app:
  name: MyApp
  security:
    username: admin
    password: secret
    roles:
      - USER
      - ADMIN

유효성 검사

@Validated 어노테이션과 함께 사용하여 프로퍼티 값의 유효성을 검사할 수 있습니다:

import javax.validation.constraints.NotNull;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.validation.annotation.Validated;

@ConfigurationProperties(prefix = "app")
@Validated
public class AppProperties {
    @NotNull
    private String name;

    @Min(0)
    @Max(100)
    private int threshold;

    // getters and setters
}

동적 바인딩

@ConfigurationProperties는 동적으로 프로퍼티를 바인딩할 수 있습니다. 예를 들어, Map을 사용하여 알 수 없는 프로퍼티들을 캡처할 수 있습니다:

@ConfigurationProperties(prefix = "app")
public class AppProperties {
    private Map<String, String> additionalHeaders = new HashMap<>();

    // getter and setter
}

이는 다음과 같은 프로퍼티와 매핑됩니다:

app.additional-headers.header1=value1
app.additional-headers.header2=value2

프로파일별 설정

@ConfigurationProperties와 프로파일을 함께 사용하여 환경별로 다른 설정을 할 수 있습니다:

app:
  name: MyApp

---
spring:
  profiles: development
app:
  name: MyApp-Dev

---
spring:
  profiles: production
app:
  name: MyApp-Prod

테스트

@ConfigurationProperties 클래스를 테스트할 때는 @EnableConfigurationProperties 어노테이션을 사용할 수 있습니다:

@SpringBootTest
@EnableConfigurationProperties(value = AppProperties.class)
@TestPropertySource("classpath:test-app.properties")
class AppPropertiesTest {

    @Autowired
    private AppProperties appProperties;

    @Test
    void testAppProperties() {
        assertEquals("TestApp", appProperties.getName());
        assertEquals(50, appProperties.getThreshold());
    }
}

베스트 프랙티스

  1. 명확한 구조화: 관련 프로퍼티들을 논리적으로 그룹화하세요.
  2. 기본값 설정: 가능한 경우 의미 있는 기본값을 제공하세요.
  3. 유효성 검사 활용: 중요한 프로퍼티에 대해서는 유효성 검사를 적용하세요.
  4. 문서화: 각 프로퍼티의 목적과 예상 값 범위를 주석으로 문서화하세요.
  5. 불변성 고려: 가능한 경우 프로퍼티를 불변으로 만들어 보세요.

주의사항

  1. 순환 의존성: @ConfigurationProperties 클래스 간의 순환 의존성을 피하세요.
  2. 빈 생성 시점: @ConfigurationProperties는 빈 생성 시점에 바인딩되므로, 동적 변경이 필요한 경우 다른 방법을 고려해야 합니다.
  3. 민감한 정보: 비밀번호 등 민감한 정보는 암호화하거나 외부 보안 저장소를 사용하세요.

결론

@ConfigurationProperties는 스프링 부트 애플리케이션의 설정을 타입 안전하고 구조화된 방식으로 관리할 수 있게 해주는 강력한 기능입니다. 이를 통해 애플리케이션의 설정을 더 쉽게 관리하고, 오류를 줄이며, 코드의 가독성을 높일 수 있습니다.

연관 포스팅

@Value
@Configuration
@Profile
@PropertySource
@EnableConfigurationProperties

profile
HelloMeow~!

0개의 댓글