HomeAboutMeBlogGuest
© 2025 Sejin Cha. All rights reserved.
Built with Next.js, deployed on Vercel
🤩
개발
/
Spring
Spring
/
🎧
Spring Framework 핵심개념(Core)
/
⛑️
Environment(Properties & Profile)
⛑️

Environment(Properties & Profile)

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가 바뀌게 되는 것
notion image
var applicationContext = new AnnotationConfigApplicationConext(AppConfiguration.class); var environment = applicationContext.getEnvironment(); environment.getProperty("kdt.version"); // 이와 같은 방식으로 프로퍼티 접근이 가능함

Externalized Configuration

[ Spring Boot Docs ] 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:
  1. Command line arguments.
  1. Java System properties (System.getProperties())
  1. OS environment variables.
  1. @PropertySource annotations on your @Configuration classes
  1. Application properties outside of your packaged jar (application.properties including YAML and profile variants)
  1. Application properties packaged inside your jar (application.properties including YAML and profile variants)
  1. 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"));
해당 환경변수를 설정한 뒤 위의 코드를 호출해보면 timeZone이 바뀐것을 확인할 수 있음
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

https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-property-source-abstraction 참고
  1. ServletConfig parameters
  1. ServletContext parameters
  1. JNDI environment variables
  1. JVM system properties ( -D commane-line arguments)
  1. 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그룹 만들기

🏉
@ConfigurationProperties
 

Environment를 통한 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 실행 시킬 때, 아래와 같이 파라미터로 주도록
    • notion image

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 설정도 가능
notion image
notion image