어플리케이션을 구동하기 위해 사용되는 설정값들을 어플리케이션이 돌아가는 플랫폼안에서 보통 환경변수 혹은 파일안에 저장해두고 쓰는데 어플리케이션 설정값을 Zookeepr, AWS Secrets 과 같은 외부 서비스에서 불러들이거나 보안을 위해 설정값들을 메모리 안에서만 저장이 필요한 경우에 활용 가능한 방법이다.

Spring boot 에서 만 활용 가능한 방법

EnvironmentPostProcessor 를 활용

public class PriceCalculationEnvironmentPostProcessor implements EnvironmentPostProcessor {

    @Override
    public void postProcessEnvironment(ConfigurableEnvironment environment, 
      SpringApplication application) {
        PropertySource<?> 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));
    }

}

Spring boot 와 Spring boot를 사용하지 않는 환경에서 활용 가능한 방법

ApplicationContextInitializer 를 활용한 방법

먼저 아래와 같이 프로퍼티 값을 오버라이드 하는 코드를 작성해준다.

public class PropertyOverrideContextInitializer
  implements ApplicationContextInitializer<ConfigurableApplicationContext> {
    @Override
    public void initialize(ConfigurableWebApplicationContext applicationContext) {
        ConfigurableEnvironment environment = applicationContext.getEnvironment();
        MyConfigProps configProps = Binder.get(environment).bind("my-config", MyConfigProps);
        System.out.println(configProps.getHomekey());
    }
  }

여기서 네가지 방법으로 어플리케이션에 적용 가능하다

1. web.xml 안에 있는 contextInitializerClasses 에 추가 혹은 상응하는 Java Config (Spring MVC)

    <context-param>
        <param-name>contextInitializerClasses</param-name>
        <param-value>com.xxxx.PropertyOverrideContextInitializer</param-value>
    </context-param>

 

자바로 설정시에 

 

@ContextConfiguration(initializers = PropertyOverrideContextInitializer.class)
public class AppConfig {

}

스프링만 사용시 

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
MyAppContextInitializer initializer = new MyAppContextInitializer();
initializer.initialize( ctx );

ctx.register( com.my.classpath.StackOverflowConfiguration.class );
ctx.refresh()

JobLauncher launcher = context.getBean(JobLauncher.class);

 

2. META-INF/spring.factories 추가하여 자동 설정 추가 (Spring Boot) 

org.springframework.context.ApplicationContextInitializer=
org.springframework.boot.context.PropertyOverrideContextInitializer

3. 어플리케이션 추가 실행코드에 추가코드에 추가하는 방법 (Spring boot)

application.addInitializers(PropertyOverrideContextInitializer.class);
application.run(args);

혹은

new SpringApplicationBuilder(YourApp.class)
    .initializers(PropertyOverrideContextInitializer.class);
    .run(args);

4. context.initializer.classes 프라퍼티 설정 (Spring boot)

context.initializer.classes=com.xxxx.PropertyOverrideContextInitializer

참조

  1. https://www.baeldung.com/spring-tests-override-properties
  2. https://stackoverflow.com/questions/35217354/how-to-add-custom-applicationcontextinitializer-to-a-spring-boot-application
  3. https://stackoverflow.com/questions/35048164/spring-applicationcontextinitializer-and-properties
  4. https://stackoverflow.com/questions/13288841/applicationcontextinitializer-in-a-non-web-spring-context

+ Recent posts