Spring Boot 및 일반 Spring 환경에서 외부 서비스 기반 설정 관리 방법
어플리케이션을 구동할 때 필요한 설정값들은 보통 환경변수(Environment Variables)나 파일에 저장하여 관리합니다. 하지만 최근에는 설정값을 Zookeeper, AWS Secrets Manager와 같은 외부 서비스에서 불러오거나, 보안을 강화하기 위해 메모리 내에서만 설정값을 저장하는 방식이 점점 더 선호되고 있습니다. 이러한 요구사항을 충족시키기 위해 Spring Boot와 일반 Spring 환경에서 설정값을 효과적으로 관리하는 방법을 소개합니다.
Spring Boot에서 환경 설정값 관리하기
Spring Boot는 EnvironmentPostProcessor를 활용하여 어플리케이션 시작 시점에 환경 설정값을 동적으로 변경하거나 추가할 수 있습니다. 이를 통해 외부 서비스에서 설정값을 불러와 적용하는 것이 가능합니다.
EnvironmentPostProcessor 활용 예제
import org.springframework.boot.SpringApplication;
import org.springframework.boot.env.EnvironmentPostProcessor;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.MapPropertySource;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.Arrays;
import java.util.List;
public class PriceCalculationEnvironmentPostProcessor implements EnvironmentPostProcessor {
private static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment";
private static final List<String> names = Arrays.asList("config.key1", "config.key2"); // 예시 키 리스트
@Override
public void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application) {
var system = environment.getPropertySources().get(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME);
Map<String, Object> prefixed = names.stream()
.collect(Collectors.toMap(this::rename, system::getProperty));
environment.getPropertySources()
.addAfter(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, new MapPropertySource("prefixer", prefixed));
}
private String rename(String originalName) {
return "prefix." + originalName; // 원하는 방식으로 키 이름 변경
}
}
적용 방법
- Spring Boot의 spring.factories 파일에 등록
src/main/resources/META-INF/spring.factories 파일에 다음 내용을 추가합니다:
org.springframework.boot.env.EnvironmentPostProcessor=\
com.example.PriceCalculationEnvironmentPostProcessor
- 어플리케이션 실행 시 자동으로 적용
Spring Boot는 spring.factories에 등록된 EnvironmentPostProcessor를 자동으로 감지하여 적용합니다.
Spring Boot를 사용하지 않는 환경에서 설정값 관리하기
Spring Boot가 아닌 일반 Spring 환경에서도 설정값을 외부 서비스에서 불러오거나 메모리 내에서 관리할 수 있습니다. 이를 위해 ApplicationContextInitializer를 활용할 수 있습니다.
ApplicationContextInitializer 활용 예제
import org.springframework.context.ApplicationContextInitializer;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.boot.context.properties.bind.Binder;
public class PropertyOverrideContextInitializer
implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
var environment = applicationContext.getEnvironment();
MyConfigProps configProps = Binder.get(environment)
.bind("my-config", MyConfigProps.class)
.orElse(new MyConfigProps());
System.out.println(configProps.getHomekey());
// 추가 설정 로직 구현
}
}
적용 방법
ApplicationContextInitializer를 적용하는 방법은 여러 가지가 있습니다. 아래에 네 가지 주요 방법을 소개합니다.
- web.xml 또는 Java Config에서 contextInitializerClasses 추가
web.xml을 사용하는 경우:
<context-param>
<param-name>contextInitializerClasses</param-name>
<param-value>com.example.PropertyOverrideContextInitializer</param-value>
</context-param>
Java Config를 사용하는 경우:
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
@ContextConfiguration(initializers = PropertyOverrideContextInitializer.class)
public class AppConfig {
// Bean 정의 등
}
- Spring만 사용하는 경우
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainApp {
public static void main(String[] args) {
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.addInitializer(new PropertyOverrideContextInitializer());
ctx.register(AppConfiguration.class);
ctx.refresh();
JobLauncher launcher = ctx.getBean(JobLauncher.class);
// 어플리케이션 로직 실행
}
}
- spring.factories 파일을 통한 자동 설정 (Spring Boot)
src/main/resources/META-INF/spring.factories 파일에 다음 내용을 추가합니다:
org.springframework.context.ApplicationContextInitializer=\
com.example.PropertyOverrideContextInitializer
- 어플리케이션 실행 시 코드로 추가 (Spring Boot)
SpringApplication을 사용하는 경우:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class YourApp {
public static void main(String[] args) {
SpringApplication application = new SpringApplication(YourApp.class);
application.addInitializers(new PropertyOverrideContextInitializer());
application.run(args);
}
}
SpringApplicationBuilder을 사용하는 경우:
import org.springframework.boot.builder.SpringApplicationBuilder;
public class YourApp {
public static void main(String[] args) {
new SpringApplicationBuilder(YourApp.class)
.initializers(new PropertyOverrideContextInitializer())
.run(args);
}
}
프로퍼티 파일을 통한 설정:
application.properties 또는 application.yml 파일에 다음과 같이 설정합니다:
context.initializer.classes=com.example.PropertyOverrideContextInitializer
결론
외부 서비스에서 설정값을 불러오거나, 보안을 강화하기 위해 메모리 내에서만 설정값을 관리하고자 할 때, Spring Boot와 일반 Spring 환경에서 제공하는 EnvironmentPostProcessor와 ApplicationContextInitializer를 활용하면 효과적으로 설정값을 관리할 수 있습니다. 각 방법은 어플리케이션의 구조와 요구사항에 따라 적절히 선택하여 적용할 수 있으며, 이를 통해 보다 유연하고 안전한 설정 관리가 가능합니다.
참고 자료
- Baeldung - Spring Tests: Override Properties
- Stack Overflow - How to add custom ApplicationContextInitializer to a Spring Boot application
- Stack Overflow - Spring ApplicationContextInitializer and properties
- Stack Overflow - ApplicationContextInitializer in a non-web Spring context
이 글이 Spring 기반 어플리케이션에서 설정값을 효과적으로 관리하는 데 도움이 되길 바랍니다. 추가적인 질문이나 의견이 있으시면 댓글로 남겨주세요!
'Java > Spring' 카테고리의 다른 글
스프링의 트랜잭션 처리 (0) | 2022.02.27 |
---|---|
스프링 프로파일 (Spring profile) 을 통해 환경별로 다른 설정을 해보자 (0) | 2016.11.24 |
Spring 내에서 리소스 불러오기 (0) | 2016.11.18 |
스프링 Properties 파일을 이용해서 설정하기 (0) | 2016.11.18 |
Mybatis + Myabtis Spring 사용시 마이바티스 설정파일 사용법 (0) | 2016.11.14 |