[스프링] 스프링 애플리케이션 프로퍼티 설정

스프링의 애플리케이션 프로퍼티 설정

애플리케이션 프로퍼티(application property)란 애플리케이션 구동을 위해 필요한 설정 정보를 말한다. 스프링 3.1 버전 이상에서 지원하는 @PropertySource 어노테이션을 사용하여 프로퍼티 파일을 애플리케이션 실행 환경에 적용할 수 있다. 어노테이션의 인자로 프로퍼티 파일의 클래스패스 경로 및 파일명을 명시하면 된다.

@Configuration
@PropertySource("classpath:application.properties")
public class Properties {
  ...
}


또한 PropertySourcesPlaceholderConfigurer 클래스와 @Value 어노테이션 및 플레이스홀더(${})를 사용하여 스프링 컨테이너가 관리하는 컴포넌트들의 필드에 애플리케이션 프로퍼티 값을 할당할 수 있다. 현재 적용된 프로퍼티 설정에 따라 프로퍼티 값이 필드 변수에 할당된다.

@Component
public class ProperyResolver {
    @Value("${prop.key}")
    private String value;
    ...
} 


프로퍼티 파일 형식이 YAML인 경우 @PropertySource 어노테이션을 통한 프로퍼티 파일 등록이 지원되지 않으므로 .properties 파일을 사용해야 한다.

스프링 부트는 기본적으로 프로퍼티 정보가 정의되어 있는 파일을 사용한다. src/main/resources 경로에 application.properties 또는 application.yaml 파일을 위치시키면 스프링은 자동으로 해당 파일을 감지하여 설정 정보를 애플리케이션 내에 자동으로 주입한다. 프로퍼티 자동 감지로 인해 @PropertySource 어노테이션을 사용하여 프로퍼티 파일을 직접 명시하지 않아도 된다. 애플리케이션 실행 시 기본 감지되는 파일 대신 다른 파일을 사용하고 싶다면 spring.config.location 공통 프로퍼티에 해당 파일을 직접 명시하면 된다.

스프링 부트 2.4.0 버전에서는 하나의 프로퍼티 파일 내에 애플리케이션 실행 환경에 따라 서로 다른 프로퍼티 정의가 가능하다. 프로퍼티 파일 내에서 #---로 다중 문서 구성을 하면 된다.

dev.prop.key=value1
#---
prod.prop.key=value2


애플리케이션 프로퍼티 설정 및 파일을 애플리케이션 실행 환경에 따라 스프링 프로파일 별로 분리할 수 있다. 예를 들어 개발 환경에서는 dev 프로파일을 사용하고 운영 환경에서는 prod 프로파일을 사용하는 경우 스프링 프로파일 설정 별로 서로 다른 애플리케이션 프로퍼티 설정이 적용되도록 하면 된다. dev 프로파일 전용 프로퍼티 파일인 application-dev.properties 파일과 prod 프로파일 전용 프로퍼티 파일인 application-prod.properties 파일을 src/main/resources 파일에 위치키시면 현재 활성화된 프로파일에 따라 서로 다른 프로퍼티 설정이 적용되어 애플리케이션이 실행된다. 애플리케이션 실행 시 활성화되는 프로파일에 대한 프로퍼티 설정이 우선 적용된다.


@ConfigurationProperties와 @ConstructorBinding

@Value을 사용하여 필드에 프로퍼티 값을 바인딩하는 대신 @ConfigurationProperties 어노테이션을 사용할 수도 있다. @ConfigurationProperties 어노테이션은 프로퍼티 값을 별도의 객체로 구조화된 바인딩 기능을 제공하며 프로퍼티 값에 대한 유효성 검사(validation) 기능도 제공한다. 클래스에 어노테이션을 설정하여 프로퍼티 바인딩을 처리한다.

@ConfigurationProperties 어노테이션을 사용한 프로퍼티 바인딩은 다음에 의해 처리된다.

  • 설정자 주입 (프로퍼티를 필드에 바인딩)
  • @ConstructorBinding을 사용하는 경우 생성자 바인딩 (프로퍼티를 생성자의 파라미터에 바인딩)


@Configuration
@ConfigurationProperties(prefix = "properties")
public class ConfigProperties {
    private String value1;
    private int value2;

    // getter 및 setter 정의
}


@ConfigurationProperties@Value 어노테이션과 달리 SpEL 표현식 평가가 되지 않는다.

@ConfigurationProperties@Value의 특징을 비교하면 다음과 같다.

  • @ConfigurationProperties
    • 장점
      • 구조화된 프로퍼티 바인딩 가능
      • 타입 안전성 제공
      • 유효성 검사 기능 지원
      • 클래스 분리나 중첩 클래스를 통한 프로퍼티 그룹화
    • 단점
      • 별도의 클래스 정의 필요
      • 간단한 값 주입 시 다소 번거로울 수 있음
  • @Value
    • 장점
      • 간단한 방법으로 값 주입 가능
      • 인스턴스의 필드에 개별적으로 직접 주입 가능
      • 문자열 표현식(SpEL) 사용 가능
    • 단점
      • 복잡한 구조의 프로퍼티 처리가 어려움
      • 타입 변환 및 유효성 검사 기능 제한

이 두 방식의 선택은 프로젝트의 복잡성과 요구사항에 따라 달라질 수 있습니다. 더 자세한 설명이 필요하시면 말씀해 주세요.

자바에서는 레코드(record)를, 코틀린에서는 데이터 클래스(data class)를 사용하면 getter나 setter 정의 없이 보다 간편하게 프로퍼티 바인딩을 수행할 수 있다.

record Data(
  ...
)
data class Data(
  ...
)


@ConstructorBinding는 설정자를 호출하지 않고 생성자 파라미터를 사용하여 프로퍼티를 바인딩하기 위해 생성자에 설정하는 어노테이션이다. 단일 생성자만 정의되어 있는 경우 @Autowired로 어노테이션을 설정하지 않더라도 생성자 바인딩이 암시적으로 수행된다.


스프링 부트 테스트를 위한 애플리케이션 프로퍼티 설정

스프링 부트는 기본적으로 테스트 실행 시 src/test/resources 경로에서 애플리케이션 프로퍼티 설정을 감지한다. 동일한 이름의 설정 파일이 프로덕션 경로인 src/main/resources에 위치하는 경우 테스트 경로의 파일이 우선 적용된다.

테스트를 위한 애플리케이션 프로퍼티 설정에는 여러 방법이 존재한다. 테스트 시 프로덕션 프로퍼티 설정을 덮어쓰기 위한 설정을 하려면 테스트 전용 프로퍼티 파일을 프로덕션 파일과 동일한 클래스패스에 위치시켜야 하므로 src/test/resources 경로에 위치시킨다. 이때 프로퍼티 파일의 이름은 프로덕션 프로퍼티 파일과 동일하게 지정한다.

- src/main/resources
  - application.properties
- src/test/resources
  - application.properties


테스트 프로퍼티 파일에는 프로덕션 프로퍼티 파일에 정의된 프로퍼티 키가 동일하게 정의되어 있어야 한다. 이 방법으로 여러 프로퍼티 키에 대한 값을 덮어쓸 수 있다. 프로퍼티 키를 동일하게 정의하지 않으면 전체 프로퍼티에 대해 덮어쓰기가 되지 않는다. 이 방법은 프로퍼티 파일을 사용하여 프로덕션 프로퍼티 설정을 덮어쓰는 것이며 프로덕션 파일 전체를 새로운 파일로 덮어쓴다.

스프링 프로파일과 @ActiveProfiles 어노테이션을 사용하는 방법도 있다. 이전 방법과 마찬가지로 테스트 전용 프로퍼티 파일을 프로덕션 프로퍼티 파일과 동일한 클래스패스에 위치시키기 위해 src/test/resources 경로에 위치시킨다. 이때 프로파일 적용을 위해 프로퍼티 파일의 이름을 application-test.properties와 같이 지정한다. 그리고 테스트 클래스에 프로파일명을 인자로 전달하여 @ActiveProfiles 어노테이션을 설정한다.

@SpringTest
@ActiveProfiles("test")
public class TestClass {
  ...
}


이 방법도 프로퍼티 파일을 사용하여 프로덕션 프로퍼티 설정을 덮어쓰는 것이며 프로덕션 프로퍼티 파일을 전체 덮어쓰는 대신 새로 정의된 프로퍼티 키에 대해서만 덮어쓴다.

@SpringBootTest 어노테이션을 사용할 수도 있다. 이 방법은 어노테이션의 properties 파라미터에 덮어쓰고자 하는 프로퍼티 키와 값을 직접 명시하여 해당 프로퍼티에 대해서만 덮어쓰는 방법이다. 프로퍼티 파일을 새로 만드는 대신 코드 내에서 직접 명시한다.

@SpringBootTest(
  properties = [
    "{prop.key1=value1}",
    "{prop.key2=value2}"
  ]
)
public class TestClass {
  ...
}


@TestPropertySource 어노테이션을 사용할 수도 있다. 이 설정은 프로덕션 설정보다 우선 적용되며 특정 테스트 컨텍스트에 대해 테스트 속성을 설정할 수 있다. 어노테이션의 인자로 프로퍼티 파일을 명시할 수 있으며 @SpringBootTest 어노테이션과 유사한 방식으로 properties 파라미터를 사용하여 특정 프로퍼티의 키와 값을 직접 넣을 수도 있다.

@TestPropertySource("/test.properties")
public class TestClass {
  ...
}
@TestPropertySource(
  properties = [
    "{prop.key1=value1}",
    "{prop.key2=value2}"
  ]
)
public class TestClass {
  ...
}


이외에 ApplicationContextInitializer 클래스를 상속하고 TestPropertySourceUtils의 메서드를 통해 프로퍼티 값을 직접 지정하는 방법을 사용할 수도 있다.


참고

Comments