Externalized Configurationapplication.yaml 외부 주입방법JVM Timezone 셋업으로 살펴보는 외부 환경변수 주입방법Properties@PropertySource@Value 를 통한 property value 주입Property Search HierarchyYaml로 프로퍼티 작성@ConfigurationProperties 로 property그룹 만들기Environment를 통한 Property 접근방법application.yaml에 값을 런타임 시에 환경 변수로 주는 방법ProfileBean에 정의 (@Profile)property를 profile별로 작성하기(Spring Boot에서만 실습함)사용 시일반적 상황Spring boot Application 에서 사용시
EnvironmentCapable interface
- Bean들에게 영향을 주는 환경. Profile에 따라서 Property가 바뀌게 되는 것

var applicationContext = new AnnotationConfigApplicationConext(AppConfiguration.class); var environment = applicationContext.getEnvironment(); environment.getProperty("kdt.version"); // 이와 같은 방식으로 프로퍼티 접근이 가능함
Externalized Configuration
Spring Boot uses a very particular
PropertySource
order that is designed to allow sensible overriding of values, properties are considered in the following order:- Command line arguments.
- Java System properties (
System.getProperties()
)
- OS environment variables.
@PropertySource
annotations on your@Configuration
classes
- Application properties outside of your packaged jar (
application.properties
including YAML and profile variants)
- Application properties packaged inside your jar (
application.properties
including YAML and profile variants)
- Default properties (specified using
SpringApplication.setDefaultProperties
)
application.yaml 외부 주입방법
$ java -jar api/build/libs/api-0.0.1.jar --spring.config.location=file:application-devserver.yaml 130 ↵
JVM Timezone 셋업으로 살펴보는 외부 환경변수 주입방법
[ Baeldung ] How to Set the JVM TimeZone
환경변수 셋업
export TZ ="America/Sao_Paulo"
Calendar calendar = Calendar.getInstance(); assertEquals(calendar.getTimeZone(), TimeZone.getTimeZone("America/Sao_Paulo"));
JVM Argument 셋업 (-Duser.timezone
)
-D 로 시작하는 부분은 JVM Argument.
- - 로 시작하는 변수들은 Spring Boot의 application.yaml에 들어가는 property 값들임
java -jar -Duser.timezone="Asia/Seoul" backend/build/libs/virtualoffice-0.0.1-SNAPSHOT.jar --spring.profiles.active=prod --server.port=5000
Properties
- [ Spring Docs ] application.yaml 에 들어갈 수 있는 프로퍼티 리스트 정리
- application.properties — Spring Boot에서 디폴트로 사용하는 프로퍼티 파일임.
- 기본 spring을 사용할 때에는 어떤 프로퍼티 파일을 사용해라 라고 알려주어야 함 (@Configuration 클래스에서
@PropertySource("application.properties")
)
- 프로퍼티 파일은 키 밸류 형태로 작성을 함
@PropertySource
- 어떤 프로퍼티 파일을 사용하라고 알려주는 어노테이션
- SpringBoot에서는 application.properties 디폴트 프로퍼티 파일
- yaml에 대해서는 지원 안함
@Value 를 통한 property value 주입
- @Value annotation 이용하면 property의 값을 컴포넌트나 다른 빈들에 주입할 수 있음
@Value(${property_name : default value})
형태로 property 값 적용 가능함- Semicolon으로 default 값 넣을 수 있다
- 또한 시스템 환경변수의 값도 넣어줄 수 있음. property 와 시스템 환경변수의 이름이 동일하면 시스템 환경변수 값 우선임
- field값 말고 함수나 생성자의 인자로도 넣어줄 수 있음
- String[] 으로 값 넣기 위해서는 yaml 에 delimiter를 , 를 이용해서 String 옆으로 쭉 이어붙이면 됨
//application.properties version= v1.0.0 kdt.version = v1.0.0 kdt.support-vendors = a, b, c, d, e, f, g kdt.minimum-order-amount = 1
@Component public class OrderProperties implements InitializingBean { @Value("${kdt.version:v0.0.0}") // kdt.version을 찾아보고 없으면 v0.0.0. // 이거 명시 안해주면 키 없으면 ${kdt.version}이게 그대로 들어가게 됨 private String version; @Value("${kdt.minimum-order-amount}") private int minimumOrderAmount; @Value("${kdt.support-vendors}") private List<String> supportVendors; @Value("${PATH}") private String path; // 시스템 환경 변수 값도 가져올 수 있음 @Override public void afterPropertiesSet() throws Exception { System.out.printf("version %s%n", version); System.out.printf("minimumOrderAmount %s%n", minimumOrderAmount); System.out.printf("supportVendors %s%n", supportVendors); } }
@Component @PropertySource("version.properties") public class VersionProvider{ private final String version; public VersionProvider(@Value("${version:v0.0.0}") String version){ this.version = version; } }
Property Search Hierarchy
- ServletConfig parameters
- ServletContext parameters
- JNDI environment variables
- JVM system properties ( -D commane-line arguments)
- JVM system environment (operating system environment variables)
Yaml로 프로퍼티 작성
kdt: version: "v1.0" minimum-order-amount: 1 support-vendors: - a - b - c - d description : |- line 1 hello world line2 xxxx line3
- array 는 - 로 쭉 아래로 나열 가능함
- 여러 줄을 쓰고 싶을 때에는 | 이 표시 이용. |- 로 표기하면 맨 마지막 줄에 줄바꿈이 있는걸 제외해 준다는 의미임
- @PropertySource 는 yaml 지원 안함
- Spring framework 에서는 PropertySourceFactory를 구현해야함. spring-boot에서는 지원함. 그 후
@PropertySource(value="application.yaml", factory= YamlPropertySourceFactory.class)
적용
public class YamlPropertySourceFactory implements PropertySourceFactory { @Override public PropertySource<?> createPropertySource(String name, EncodedResource resource) throws IOException { YamlPropertiesFactoryBean bean = new YamlPropertiesFactoryBean(); bean.setResources(resource.getResource()); var properties = bean.getObject(); return new PropertiesPropertySource(resource.getResource().getFilename(), properties); } }
@ConfigurationProperties 로 property그룹 만들기
@ConfigurationPropertiesEnvironment를 통한 Property 접근방법
// 1. environment 얻어와서 거기서 property에 접근 var applicationContext = new AnnotationConfigApplicationConext(AppConfiguration.class); var environment = applicationContext.getEnvironment(); environment.getProperty("kdt.version"); // 이와 같은 방식으로 프로퍼티 접근이 가능함 // 2. ConfigurationProperties 클래스를 의존성 주입 받아서 property값들에 접근하기
application.yaml에 값을 런타임 시에 환경 변수로 주는 방법
spring: datasource: driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://localhost:3306/aircnc?serverTimezone=UTC&characterEncoding=UTF-8 username: ${db.username:root} password: ${db.password:1234}
- : 뒤에 있는 값이 default 값임
- 이렇게 하고 idea 실행 시킬 때, 아래와 같이 파라미터로 주도록

Profile
Bean에 정의 (@Profile)
profile별로 application context에 올라가는 빈을 정의할 수 있음
- local, dev, staging, production 등 이런 식으로 그룹화해서 profile을 만들어서 사용할 수 있음
- application 실행 시 그런 프로파일들 적용해서 실행되도록 할 수 있음
- Bean 정의하면서도 할 수 있고 stereotype annotation을 통해서도 할 수 있음
@Repository @Profile("dev") public class MemoryVoucherRepository implements VoucherRepository{ } @Repository @Profile("local") public class MemoryVoucherRepository implements VoucherRepository{ } AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(AppConfig.class); var environment = context.getEnvironment(); environment.setActiveProfiles("dev"); context.refresh(); var voucherRepository = context.getBean(VoucherRepository.class); @Bean @Profile("dev") // 이런 방식으로
property를 profile별로 작성하기(Spring Boot에서만 실습함)
- 그러나 이 기능은 spring boot에서만 지원되는 기능임. spring boot application으로 실행해야 구분해서 property값 가져올 수 있음
spring.config.activate.on-profile: dev kdt: version: "v1.0" minimum-order-amount: 1 support-vendors: - a - b - c - d description : |- line 1 hello world line2 xxxx line3 --- // 이 부분 있어야함! 그래야 위 아래 구분이 됨 spring: config: activate: on-profile: local kdt: version: "v1.0" minimum-order-amount: 1 support-vendors: - dev-a - dev-b - c - d description : |- line 1 hello world line2 xxxx line3
- 위와 같이 한 파일에 작성할 수도 있고, application-dev.yaml, application-local.yaml 이런식으로 파일 따로 작성해도 됨. dev, local profile 알아서 읽어줌(Spring Boot에서)
- 이 때 application.yaml 파일은 profile 을 설정해주지 않았을때 읽게 되는 파일임. 만약 profile을 설정해 주지 않고 Bean들에
@Profile(”dev”)
@Profile(”local”)
이렇게만 설정해주게 되면, candidate bean이 없다는 에러가 발생함(”default”
도 추가해주어야..)
사용 시
일반적 상황
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); context.register(AppConfig.class); var environment = context.getEnvironment(); environment.setActiveProfiles("local"); context.refresh(); System.out.println(context.getBean(Properties.class).getSupportVendors());
Spring boot Application 에서 사용시
SpringApplication springApplication = new SpringApplication(App.class); springApplication.setAdditionalProfiles("local"); var applicationContext = springApplication.run(args); var properties = applicationContext.getBean(Properties.class);
- SpringBootApplication인 경우에는 아래의 Edit Configuration에서도 Active profile 설정이 가능함
- 또는 Program arguments에
—spring.profiles.active=dev
와 같은 방식으로 명시해줌으로써 profile 설정도 가능

