일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 네트워크
- spring webflux
- Galera Cluster
- redis
- Proxy
- Java
- 운영체제
- Heap
- Data Structure
- react
- 백준
- 자바
- Algorithm
- MSA
- Spring
- mongoDB
- 알고리즘
- Kafka
- 컴퓨터구조
- C
- JPA
- 파이썬
- JavaScript
- OS
- 디자인 패턴
- MySQL
- design pattern
- IT
- 자료구조
- c언어
Archives
- Today
- Total
시냅스
JVM, Spring 에서의 시스템 변수와 환경변수 이해 본문
정보 관리를 위해 Java/Spring 환경에서의 시스템 변수, 환경변수의 활용에 대한 글을 작성했습니다.
Vault 와 같은 툴을 사용할 수도 있지만 그 전에 application level 에서의 이해를 돕기 위해 글을 작성하였습니다.
시스템 중요 정보를 외부에서 할당할 때 정보은닉을 지키며 할당한 데이터를 사용하는 방법에 대해 알아봅니다.
아래에서는 OS 환경 변수, 시스템 변수, 나아가 application.yml 이 어떤 순서로 할당되는지에 대해 알아봅니다.
System.getenv
- JVM 이 실행되는 운영체제의 환경변수를 가져옵니다.
- 대개 apllication 을 실행하는 OS 의 환경변수 이거나 build time 에 shell / Docker / k8s 등에서 설정하기도 합니다.
- OS 전역의 변수를 가져올 수 있습니다.
- Java application이 시작될 때, 부모 프로세스의 환경변수를 복제하여 상속받습니다. (Clone Inheritance)
- 따라서 OS에서 복사해온 immutable 한 변수이므로 변경 / 수정이 불가능합니다.
public class Main {
public static void main(String[] args) {
String envVar = System.getenv("MY_ENV_VAR");
System.out.println("Environment variable: " + envVar);
}
}
System.getProperty
- 로컬 시스템 및 구성에 대한 정보를 제공합니다.
- JVM 에 국한됩니다.
- VM Options 로 설정할 수 있습니다.
- -d 옵션을 사용합니다.
- runtime 에 변경 / 수정이 가능합니다.
// java -Dmy.sys.prop=hello
public class Main {
public static void main(String[] args) {
String sysProp = System.getProperty("my.sys.prop");
System.out.println("System property: " + sysProp); // System property: hello
System.setProperty("my.sys.prop", "hello agian");
System.out.println("System property: " + sysProp); // System property: hello again
}
}
Spring 환경변수 참조
- Environment 인터페이스, 혹은 @Value, @ConfigurationProperties 을 사용하여 환경변수, 시스템 변수를 참조할 수 있습니다.
- 이때, 같은 key 를 가진다면 우선순위에 따라 할당됩니다.
- 우선 순위 - Spring 공식문서
- 또한 Spring Boot 에서 값을 할당해줘야 하므로 Spring app 의 context load 이전에는 참조할 수 없습니다.
- 만약 할당한 환경변수가 context 종속적(build time 에만 사용)이고 context load 이전 (@PostConstruct 등)에 변수를 사용해야 한다면 이 방법으로는 사용할 수 없습니다.
- 아래에서 Spring 의 생명주기와 함께 변수 할당 시점을 설명합니다.
- application.yml
- SpEL 의 꼴로 시스템 / 환경 변수를 할당할 수 있게 합니다. ( ${} )
- SpEL 의 value 는 application 이 시작되는 단계에 할당됩니다.
- Spring Boot 에서 제공하는 AutoConfiguration 에 많이 활용됩니다.
- DB, Redis ...etc
# application.yml
my:
prop: ${SOME_DATA} # SOME_DATA=hello
@RestController
public class MyController {
@Value("${my.prop}")
private String myProp;
@GetMapping("/prop")
public String getProp() {
return "Property value: " + myProp; //Property value: hello
}
}
Spring Lifecycle 로 보는 변수 할당 시점
- JVM 시작
- OS 환경변수 참조 가능 (System.getenv)
- JVM Property 참조 가능 (System.getProperty)
- spring app context initializing
- spring core
- 이때 bean 에 대한 주입을 마치고 나면 @PostContruct 가 실행됩니다.
- 비슷한 시기에 BeanFactoryPostProcessor 에서 @Value 에 참조 값들을 확인하고 설정합니다.
- 따라서 같은 시기에 할당되므로 @PostConstruct 에서는 @Value 를 참조할 수 없습니다.
- 또는 @Value 자체를 Constructor 로 DI 받아야 합니다.
- spring web initializing
- Spring MVC, DispatcherServlet, web...
- context load
- 참고
- application.yml 의 value ( ${} ) 는 spring app context initializing 단계에서 이미 할당되어 있습니다.
- 다만, 그 값을 불러오는 @Value 등에서 사용이 bean 이 다 주입된 이후에 가능합니다.
- 따라서 application.yml 에 설정된 값들을 통해 AutoConfiguration 이 가능합니다.
참고
https://www.baeldung.com/java-system-get-property-vs-system-getenv
'Java, Spring' 카테고리의 다른 글
Spring WebFlux 이해하기 - Reactor (1) | 2024.02.03 |
---|---|
Spring WebFlux 이해하기 - Reactive Streams (0) | 2024.02.03 |
Spring Boot 3++ 를 위한 Spring Batch migration 요약 (1) | 2023.11.18 |
Spring 동시성 문제 해결 (비관적 락, Redis 분산락을 적용한 Annotation AOP) (0) | 2023.07.23 |
JWT 대신 Session 을 쓰는 이유 (Redis Session Clustering, Spring Security) (2) | 2023.07.17 |
Comments