해당 글에서는 Spring Boot Configuration Processor를 활용하여서 외부 설정 소스 파일(yaml/yml, properties)을 불러오는 다양한 방법에 대해 알아봅니다
1) spring-boot-configuration-processor
💡 spring-boot-configuration-processor
- Spring Boot 애플리케이션의 외부화된 구성 및 속성 파일에 정의된 속성에 대해 쉽게 접근하여 값을 가져오는 기능을 제공하는 라이브러리입니다. - 해당 라이브러리에서 @ConfigurationProperties 어노테이션을 통해서 적용된 클래스(class), 레코드(record)를 분석하여 메타데이터를 생성합니다.
1. 주요 특징
특징
설명
타입 안전성
컴파일 시점에서 타입 오류를 감지하여 런타임 에러를 방지합니다. 설정 값의 타입이 명확히 정의되어 있어 잘못된 타입 사용을 미리 방지할 수 있습니다.
유연성
다양한 형식(YAML/YML, Properties 등)의 설정 파일을 지원하며, 필요에 따라 동적으로 설정을 변경할 수 있습니다.
계층 구조
복잡한 설정을 계층적으로 구성할 수 있어 관련 설정을 그룹화하고 구조화하여 관리할 수 있습니다. 이는 설정의 가독성과 유지보수성을 향상시킵니다.
검증
@Validated 어노테이션을 통해 설정 값의 유효성을 검사할 수 있습니다. 이를 통해 잘못된 설정 값이 애플리케이션에 주입되는 것을 방지할 수 있습니다.
자동 완성 기능
IDE에서 설정 파일 작성 시 자동 완성 기능을 제공합니다. 이는 개발자의 생산성을 높이고 설정 오류를 줄이는 데 도움을 줍니다.
2. configuration-processor에서의 메타데이터(Meta Data)
💡 configuration-processor에서의 메타데이터(Meta Data) - configuration-processor에서는 @ConfigurationProperties(클래스)를 통해서 클래스, 레코드를 분석하여 메타데이터를 자동으로 생성합니다. - 이는 외부 설정 소스(yaml/yml, properties 파일 등)를 통해서 클래스의 멤버 변수와 매핑이 되어서 값이 설정이 됩니다.
spring:
security:
oauth2:
client:
# OAuth2 인증 제공자에 대한 설정 정보를 포함합니다.
provider:
kakao:
authorization-uri: https://kauth.kakao.com/oauth/authorize
💡 configuration-processor 설정을 통해 위에 yml 파일과 OAuth2ClientProperties 클래스가 매핑이 되며, 멤버 변수로 각각의 값이 매핑이 됩니다.
@ConfigurationProperties(prefix = "spring.security.oauth2.client")
public record OAuth2ClientProperties(ProviderProperties provider) {
public record ProviderProperties(ProviderConfig kakao) {
public record ProviderConfig(String authorizationUri) {
}
}
}
3. 메타데이터와 클래스-속성 파일 매핑의 관계
💡 메타데이터와 클래스-속성 파일 매핑의 관계
- 메타데이터는 클래스와 속성 파일 간의 "브리지" 역할을 하며, 매핑 과정의 정확성과 효율성을 크게 향상합니다.
1. 메타데이터 생성 - spring-boot-configuration-processor는 @ConfigurationProperties 어노테이션이 적용된 클래스를 분석하여 메타데이터를 자동으로 생성합니다.
2. 매핑 정보 제공 - 생성된 메타데이터는 클래스의 구조, 속성 이름, 타입 등의 정보를 포함하여 Spring Boot가 속성 파일과 클래스를 정확히 매핑할 수 있도록 돕습니다.
3. IDE 지원 - 메타데이터는 IDE에서 자동완성, 문서화, 유효성 검사 등의 기능을 제공하여 개발자가 속성 파일을 더 쉽고 정확하게 작성할 수 있게 합니다.
4. 런타임 바인딩 - Spring Boot는 이 메타데이터를 사용하여 런타임에 속성 파일의 값을 클래스의 필드에 정확하게 바인딩합니다.
- yml 파일 형태로 구성이 되어 있으며 Spring Boot OAuth 2.0 기반의 카카오, 네이버 로그인에 대한 설정 정보입니다.
spring:
security:
oauth2:
client:
# OAuth2 인증 제공자에 대한 설정 정보를 포함합니다.
provider:
kakao:
authorization-uri: <https://kauth.kakao.com/oauth/authorize>
token-uri: <https://kauth.kakao.com/oauth/token>
user-info-uri: <https://kapi.kakao.com/v2/user/me>
user-name-attribute: id
naver:
authorization-uri: <https://nid.naver.com/oauth2.0/authorize>
token-uri: <https://nid.naver.com/oauth2.0/token>
user-info-uri: <https://openapi.naver.com/v1/nid/me>
user-name-attribute: id
# 클라이언트 애플리케이션(Spring Boot)에 대한 설정을 포함합니다.
registration:
kakao:
client-id: xx
client-secret: xx
redirect-uri:
authorization-grant-type: authorization_code
client-authentication-method: POST
client-name: kakao
scope:
- name
- profile_nickname
- account_email
naver:
client-id: xx
client-secret: xx
redirect-uri:
authorization-grant-type: authorization_code
client-authentication-method: client_secret_post
client-name: naver
scope:
- nickname
- email
- profile_image
3. 조회 방법 확인 : @value
💡조회 방법 확인 : @value
- 기존의 @Value 어노테이션을 통해 properties 파일을 가져왔습니다. 이는 타입의 안정성도 보장이 되지 않고, 값을 찾는데 복잡하다는 문제점이 있었습니다. - 이를 해결하기 위한 방법으로 properties 파일을 spring-boot-configuration-processor를 활용하여서 객체 형태로 구성합니다.
어노테이션
설명
@Value
Spring Framework에서 제공하는 어노테이션으로, 외부 설정 파일(properties, YAML 등)의 값을 Spring 빈의 필드나 메서드 파라미터에 주입하는 데 사용됩니다. 주로 단일 값을 주입할 때 사용되며, 표현식을 통해 복잡한 값도 주입할 수 있습니다.
3) spring-boot-configuration-processor 활용하기 : 생성자(Getter) 이용 방법
💡 spring-boot-configuration-processor 활용하기 : 생성자(Getter) 이용 방법
- 이 방식은 생성자를 통해 설정 값을 주입받는 방식입니다. 이는 불변성을 보장하며, 모든 필드가 final로 선언될 수 있습니다. - 생성자를 통해 모든 필드가 초기화되므로, 누락된 설정 값을 쉽게 발견할 수 있습니다. 테스트하기 쉽고, 스프링의 생성자 주입 방식과 일관성이 있습니다.
1. OAuth2ClientProperties
💡OAuth2ClientProperties
- 아래와 같은 구성을 통해서 application.properties 또는 application.yml 파일의 설정을 타입 안전하게 자바 객체로 매핑할 수 있습니다. 이를 통해 설정 값에 쉽게 접근하고 관리할 수 있습니다.
- @ConfigurationProperties 어노테이션을 통해 'spring.security.oauth2.client' 접두사로 시작하는 설정을 매핑합니다. - 구성은 크게 ProviderProperties와 RegistrationProperties 두 개의 내부 클래스로 구성되어 있습니다. - 각 내부 클래스는 카카오와 네이버에 대한 설정을 포함합니다. - ProviderConfig 클래스는 인증 제공자의 URI 정보를 포함합니다. - RegistrationConfig 클래스는 클라이언트 ID, 비밀키, 리다이렉트 URI 등의 클라이언트 등록 정보를 포함합니다.
어노테이션
설명
@ConfigurationProperties
외부 설정 파일의 속성을 자바 객체에 바인딩하는데 사용됩니다. 특정 접두사를 가진 속성들을 하나의 클래스에 매핑할 수 있습니다.
- Main Class 내에서 구성한 properties 파일을 스캔합니다. 이는 단건 클래스로 조회 및 등록을 하거나 혹은 패키지 경로에 따라 여러 클래스를 조회 및 등록하는 방법이 있습니다.
- @EnableConfigurationProperties(OAuth2ClientProperties.class)의 경우는 OAuth2ClientProperties 클래스 내에서 구성한 Properties 파일을 매핑합니다. - 그리고 @ConfigurationPropertiesScan("com.adjh.springbootoauth2.config.properties") 경우에는 “com.adjh.springbootoauth2.config.properties” 패키지 내의 properties를 매핑한 파일들을 모두 스캔합니다.
어노테이션
설명
@EnableConfigurationProperties
@ConfigurationProperties가 적용된 클래스를 활성화하고 빈으로 등록합니다. 주로 메인 애플리케이션 클래스나 설정 클래스에서 사용됩니다.
@ConfigurationPropertiesScan
지정된 패키지 내의 모든 @ConfigurationProperties 클래스를 스캔하고 빈으로 등록합니다.
package com.adjh.springbootoauth2;
import com.adjh.springbootoauth2.config.properties.OAuth2ClientProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
// 단건 클래스로 조회 및 등록
@EnableConfigurationProperties(OAuth2ClientProperties.class)
// or
// 패키지 경로에 따라 여러 클래스 조회 및 등록
@ConfigurationPropertiesScan("com.adjh.springbootoauth2.config.properties")
public class SpringBoot3SecurityOauth2Application {
public static void main(String[] args) {
SpringApplication.run(SpringBoot3SecurityOauth2Application.class, args);
}
}
3. Properties 파일 호출
💡Properties 파일 호출 - 아래와 같이 프로퍼티의 값을 객체 내애서 불러와서 클래스 내에서 사용이 됩니다. 해당 방식에서는 특히 이전에 @Getter를 통해서 .get() 메서드를 통해 데이터를 호출해 옵니다. - 또한, init() 메서드에 @PostConstruct 어노테이션이 붙어있어, 빈 생성 후 자동으로 실행되며, OAuth2ClientProperties 객체로부터 각 설정 값을 가져와 필드에 할당합니다.
4) spring-boot-configuration-processor 활용하기 : 레코드 타입
💡 spring-boot-configuration-processor 활용하기 : 레코드 타입
- Java 14 버전에 추가된 레코드 타입을 사용하여 설정 값을 매핑하는 방식입니다. - 이는 생성자 타입보다 간결한 코드로 설정 값을 정의하고 접근할 수 있습니다.@Getter 어노테이션을 통한 메서드 대신에 필드 이름을 직접 메서드처럼 호출을 한다는 장점이 있습니다.
💡 OAuth2ClientProperties - @ConfigurationProperties 어노테이션을 사용하여 'spring.security.oauth2.client' 접두사로 시작하는 설정을 매핑합니다. - 레코드(record) 타입을 사용하여 불변성을 보장하고 간결한 코드를 작성했습니다.
- OAuth2ClientProperties 클래스는 ProviderProperties와 RegistrationProperties 두 개의 내부 레코드로 구성됩니다. - ProviderProperties는 카카오와 네이버의 인증 제공자 설정을 포함합니다. - RegistrationProperties는 카카오와 네이버의 클라이언트 등록 정보를 포함합니다. - 각 설정에는 인증 URI, 토큰 URI, 사용자 정보 URI, 클라이언트 ID, 비밀키, 리다이렉트 URI 등의 정보가 포함됩니다.
어노테이션
설명
@ConfigurationProperties
외부 설정 파일의 속성을 자바 객체에 바인딩하는데 사용됩니다. 특정 접두사를 가진 속성들을 하나의 클래스에 매핑할 수 있습니다.
package com.adjh.springbootoauth2.config.properties;
import lombok.Getter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.List;
@ConfigurationProperties(prefix = "spring.security.oauth2.client")
public record OAuth2ClientProperties(ProviderProperties provider, RegistrationProperties registration) {
public record ProviderProperties(ProviderConfig kakao, ProviderConfig naver) {
public record ProviderConfig(String authorizationUri, String tokenUri, String userInfoUri, String userNameAttribute) {
}
}
public record RegistrationProperties(RegistrationConfig kakao, RegistrationConfig naver) {
public record RegistrationConfig(String clientId, String clientSecret, String redirectUri, String authorizationGrantType, String clientAuthenticationMethod,
String clientName, List<String> scope) {
}
}
}
2. SpringBoot3SecurityOauth2Application
💡 SpringBoot3SecurityOauth2Application
- Main Class에 @EnableConfigurationProperties을 통해서 Properties 클래스를 등록해 줍니다. 이는 Spring 애플리케이션 내에 컨텍스트를 등록하기 위해 수행합니다.
어노테이션
설명
@EnableConfigurationProperties
@ConfigurationProperties가 적용된 클래스를 활성화하고 빈으로 등록합니다. 주로 메인 애플리케이션 클래스나 설정 클래스에서 사용됩니다.
@ConfigurationPropertiesScan
지정된 패키지 내의 모든 @ConfigurationProperties 클래스를 스캔하고 빈으로 등록합니다.
package com.adjh.springbootoauth2;
import com.adjh.springbootoauth2.config.properties.OAuth2ClientProperties;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
// 단건 클래스로 조회 및 등록
@EnableConfigurationProperties(OAuth2ClientProperties.class)
// or
// 패키지 경로에 따라 여러 클래스 조회 및 등록
@ConfigurationPropertiesScan("com.adjh.springbootoauth2.config.properties")
public class SpringBoot3SecurityOauth2Application {
public static void main(String[] args) {
SpringApplication.run(SpringBoot3SecurityOauth2Application.class, args);
}
}
3. Properties 파일 호출
💡 Properties 파일 호출
- 아래와 같이 프로퍼티의 값을 객체 내애서 불러와서 클래스 내에서 사용이 됩니다. 해당 방식에서는 특히 생성자 @Getter를 통한 .get() 메서드가 아닌 속성값을 통해 데이터를 호출해 옵니다.
- 또한, init() 메서드에 @PostConstruct 어노테이션이 붙어있어, 빈 생성 후 자동으로 실행되며, OAuth2ClientProperties 객체로부터 각 설정 값을 가져와 필드에 할당합니다.