환경 변수를 효율적으로 관리하는 것은 모든 스프링 부트 애플리케이션에서 중요한 부분입니다.
저는 이부분에서 @Value 어노테이션을 사용해서 환경변수를 매핑해서 변수로 사용하곤 했었는데요.
하지만 지금은 @ConfigurationProperties를 써서 환경변수 추가/수정/제거 등 관리하고 있습니다.
이 글에서는 @ConfigurationProperties가 @Value보다 왜 더 효율적인지를 알아보겠습니다.
@Value
@Value 어노테이션은 환경 변수를 주입하기에 아주 간단한 방법입니다. 하지만 매번 하드코딩으로 환경 변수의 주소를 작성해야하고, 해당 변수를 사용하는 여러 곳에 중복 코드가 발생하게 됩니다.
또, 이러한 프로퍼티가 많아질수록 관리가 어려워집니다.
// jwtProvider
@Component
class JwtTokenProvider(
@Value("\${custom.jwt.token.access-expiration-time}")
private var accessExpirationTime: Long,
@Value("\${custom.jwt.token.refresh-expiration-time}")
private var refreshExpirationTime: Long,
)
// jwtUtil
@Component
class JwtTokenUtil(
@Value("\${custom.jwt.token.access-expiration-time}")
private var accessExpirationTime: Long,
@Value("\${custom.jwt.token.refresh-expiration-time}")
private var refreshExpirationTime: Long,
)
@ConfigurationProperties
@ConfigurationProperties 어노테이션은 프로퍼티를 하나의 클래스에 저장하여 관리할 수 있게 할 수 있습니다. 프로퍼티를 다음과 같이 관리했을 때 얻는 이점은 다음과 같습니다.
1. 여러 클래스에서 하드코딩으로 수정해야했던 경로나 타입들을 하나의 클래스에서 자동으로 관리할 수 있음
2. 도메인 별로 관련된 프로퍼티를 클래스를 나누어 묶어서 관리할 수 있게되면서, 코드의 가독성과 구조가 향상된
3. IDE에서 자동완성으로 사용할 수 있음
하지만 작성시에 매우 유의해야할 부분이 있습니다. yml이나 properties 파일에 작성된 경로에 맞게 변수 이름을 설정해야 환경변수를 알맞게 매핑할 수 있습니다. 다음과 같이 말입니다.
@ConfigurationProperties(prefix = "custom")
data class AccountProperties @ConstructorBinding constructor(
val jwt: JwtProperties
) {
val nameJson: String
get() = "account-api/src/main/resources/names/names.json"
data class JwtProperties(
val accessExpirationTime: Long,
val refreshExpirationTime: Long,
val secret: String,
)
}
// application.yml
custom:
jwt:
secret: 시크릿 코드
access-expiration-time: 900000 # 15분 -> 15 * 60 * 1000
refresh-expiration-time: 1296000000 # 15일 -> 15 * 24 * 60 * 60 * 1000
하지만 이렇게 작성했다고 해서 이 프로퍼티 클래스르는 자체적으로 스프링 빈에 등록되지 않습니다.
이클래스를 빈에 등록하고, 프로퍼티가 외부 값을 바인딩 받을 수 있도록 하려면 추가적인 설정이 필요합니다.
이를 위해 따로 클래스를 생성해주도록 하겠습니다.
@Configuration
@EnableConfigurationProperties(AccountProperties::class)
class AccountConfig
이렇게 @Configuration 어노테이션이 붙은 클래스는 빈으로 정의가 됩니다. 그리고 이전에 작성한 프로퍼티 클래스를 Enable 하면서 설정값을 바인딩할 수 있도록 하여 최종적으로 환경변수를 사용할 수 있게 됩니다. 여기서 문제가 발생하셨다면 yml에 작성된 이름과 다른 변수 이름으로 설정하셨는지 꼭 확인하셔야합니다!!!
실제 사용은 다음과 같이 의존성을 추가하여 사용합니다.
@Component
class JwtTokenProvider(
private val accountProperties: AccountProperties,
) {
...
fun createdJwtToken(username: String, authorities: String): JwtTokenResponse {
...
val accessToken: String = createdAccessToken(claims,
Date(createdTime.time + accountProperties.jwt.accessExpirationTime)
)
}
이렇게해 설정 클래스를 작성하면, 프로퍼티 클래스에 정의된 프로퍼티들은 자동으로 설정 파일의 값으로 채워지며, 이를 전체 애플리케이션에서 재사용할 수 있습니다.
'Spring' 카테고리의 다른 글
스프링에서 gpt api 사용해보기 (0) | 2024.01.16 |
---|---|
스프링에서 실시간 에러 로그를 Discord로 받는 방법 (1) | 2023.12.10 |
스프링에서 실시간 에러 로그를 Slack으로 받는 방법 (0) | 2023.11.22 |
JPA의 정적쿼리와 동적쿼리의 차이점 (0) | 2023.06.06 |
@Validated, @Valid와 @Column으로 나뉘는 유효성 검증 (0) | 2023.03.22 |
댓글