yml 설정값을 Java 객체에 바인딩하는 @ConfigurationProperties는 세팅이 제대로 안 되면 빨간 줄만 뜨고 동작하지 않는다. 의존성 추가부터 등록 방식까지 순서대로 잡아줘야 한다.
- 설정 관리와 @ConfigurationProperties — @Value와의 비교, 바인딩 개념 설명
의존성 추가
@ConfigurationProperties를 IDE에서 인식하려면 어노테이션 프로세서가 필요하다.
build.gradle에 추가한다.
annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'
추가 후 Gradle sync를 해야 적용된다. 이게 없으면 IDE에서 빨간 줄이 뜬다.
바인딩 클래스 작성
record로 작성하는 것이 가장 간결하다.
@ConfigurationProperties(prefix = "app")
public record AppConstants(UUID defaultUserUuid) {
}
prefix는 yml의 최상위 키다. 필드명은 yml의 키를 camelCase로 변환한 이름과 매핑된다.
yml 작성
app:
default-user-uuid: 00000000-0000-0000-0000-000000000000
yml 키는 kebab-case로 쓴다. Spring이 자동으로 camelCase(defaultUserUuid)로 매핑해준다.
스캔 등록
Spring이 @ConfigurationProperties 클래스를 Bean으로 등록하게 해줘야 한다. 방법은 두 가지다.
별도 Config 클래스에 분리 (권장)
메인 클래스를 건드리지 않고 설정 클래스로 분리한다.
@Configuration
@ConfigurationPropertiesScan("com.codeit.weatherfit")
public class PropertiesScanConfig {
}
@ConfigurationPropertiesScan에 베이스 패키지를 지정하면 하위 패키지에 있는 @ConfigurationProperties 클래스를 전부 스캔해서 등록한다.
메인 클래스에 직접 추가
@SpringBootApplication
@ConfigurationPropertiesScan
public class WeatherFitApplication { ... }
간단하지만 메인 클래스가 무거워진다.
설정 관련 책임을 한 곳에 모으는 게 낫다. 별도 Config 클래스로 분리하면 @ConfigurationProperties 클래스가 늘어나도 메인 클래스를 건드리지 않아도 된다.
주입해서 사용
Bean으로 등록됐으니 생성자 주입으로 쓴다.
@Service
@RequiredArgsConstructor
public class FeedService {
private final AppConstants appConstants;
public void someMethod() {
UUID defaultUuid = appConstants.defaultUserUuid();
}
}
record의 컴포넌트는 getter가 아니라 메서드 이름 그대로 호출한다. getDefaultUserUuid()가 아니라 defaultUserUuid()다.
자주 하는 실수
build.gradle에 annotationProcessor 'org.springframework.boot:spring-boot-configuration-processor'가 없으면 IDE가 @ConfigurationProperties를 인식하지 못해 빨간 줄이 뜬다. Gradle sync까지 해야 적용된다.
[!BUG] 스캔 등록을 빠뜨리는 실수
@ConfigurationProperties만 붙인다고 Bean이 되지 않는다. @ConfigurationPropertiesScan 또는 @EnableConfigurationProperties로 등록해줘야 한다. 등록하지 않으면 주입 시 NoSuchBeanDefinitionException이 발생한다.
[!BUG] yml 키를 camelCase로 쓰는 실수
yml에서 defaultUserUuid처럼 camelCase로 쓰면 일부 환경에서 인식이 안 된다. yml 키는 반드시 default-user-uuid처럼 kebab-case로 써야 한다.
[!BUG] record getter를 get~()으로 호출하는 실수
일반 클래스의 getter는 getXxx()지만 record의 접근자는 필드명 그대로다. appConstants.getDefaultUserUuid()는 컴파일 에러가 난다. appConstants.defaultUserUuid()로 써야 한다.