Allows for customization of the application’s Environment prior to the application context being refreshed.
애플리케이션 Environment를 커스터마이징할 수 있게 허락한다.
Interface representing the environment in which the current application is running. Models two key aspects of the application environment: profiles and properties.
현재 실행 중인 애플리케이션의 Environment를 나타내고 주요 측면으로 profile 과 properties를 모델링한다.
EnvironmentPostProcessor
인터페이스를 통해 애플리케이션 구동 시에 원하는 방식대로 설정 파일(yaml, properties) 또는 profile을 설정할 수 있다.
spring.profiles.include
설정 파일을 application-redis.yml, application-mysql.yml 다음과 같이 분리하여 application.yml에서 include 하여 사용하는 방식이 있다.
// application.yml
spring:
profiles:
include:
- redis
- mysql
멀티 모듈에서 다음과 같이 사용할 때 불편한 점이 존재한다. common이나 client 모듈에서 사용하는 설정 파일을 생성할 때 app 모듈로 와서 application.yml에 include 해주어야 하고 새로운 app 모듈이 생성되었을 때 필요한 부분을 copy & paste 해야 하는 번거로움이 존재한다.
설정 파일이 여러 모듈에 중복되면 동일한 설정을 여러 곳에서 반복해서 수정해야 하고 새로운 모듈 추가 시에 기존 모듈 설정을 복사해야 하는 등 관리하기 어려워질 것이고 모듈의 개수가 많아질수록 더욱더 체감될 것이다.
이러한 문제들은 설정 일관성을 무너뜨리고 유지보수의 어려움이 발생된다.
EnvironmentPostProcessor 구현
EnvironmentPostProcessor
를 이용하여 include 하지 않고 yaml 설정 파일들을 읽어 적용하는 방식을 적용하면 확장하는 데 있어 유연하게 대처할 수 있다.
class HjEnvironmentPostProcessor : EnvironmentPostProcessor {
companion object {
private const val FILE_PATH = "classpath*:"
private const val FILE_PATTERN = "application-*"
private val YAML_EXTENSIONS = listOf(".yml", ".yaml")
}
override fun postProcessEnvironment(environment: ConfigurableEnvironment, application: SpringApplication) {
val sources = environment.propertySources
val activeProfiles = environment.activeProfiles
val resolver = PathMatchingResourcePatternResolver()
try {
val resources = mutableListOf<Resource>()
YAML_EXTENSIONS.forEach {
resources.addAll(resolver.getResources(FILE_PATH + FILE_PATTERN + it))
}
resources.forEach { resource ->
YamlPropertySourceLoader().load(resource.filename, resource)
.filter {
activeProfiles.any { activeProfile -> activeProfile == (it.source as Map<*, *>)["spring.config.activate.on-profile"]?.toString() }
}
.forEach {
sources.addLast(it)
}
}
} catch (e: Exception) {
throw RuntimeException("Failed to load configuration files", e)
}
}
}
// path: src.main.resources.META-INF
// file name: spring.factories
org.springframework.boot.env.EnvironmentPostProcessor=\
me.hajoo.hj.yaml.importer.HjEnvironmentPostProcessor