프로젝트 도중
properties에 있는 값을 가져와 java static 변수로 초기화 해서 사용해야 하는 상황이 왔습니다.
하지만
아직도 저는 @value로 가져오는 값 초기화와 static 클래스 변수 초기화의 순서 차이를 뚜렷하게 알지를 못합니다.
저의 경우 static 블록으로 static 변수를 초기화 해주는 SET메소드를 불러와 static 클래스 변수를 초기화 하기 때문에
아래에 써내려갈 해결책과는 케이스가 달라서 저는 적용을 못했습니다.
이러한 해결책을 찾으시는 분들에게 도움이 되고자 링크를 적겠습니다.
1. bean으로 해결
https://stay-hungry.tistory.com/26
@postConstruct로 해결
https://yonguri.tistory.com/100
@value set으로 해결
https://www.baeldung.com/spring-inject-static-field
+@
변수의 초기화 순서는
- 클래스 변수
- 클래스 메서드
- 인스턴스 변수
- 인스턴스 메서드
- 로컬 변수
- 로컬 메서드
순서 입니다.
클래스변수(static)가 클래스초기화 되면서 제일 먼저 초기화가 실행됩니다.
하지만 static변수가 인스턴스변수나 인스턴스 메서드를 참조하고 싶어도 아직 다른 객체들은 생성되기 전 시점입니다.
클래스가 로드되고 인스턴스 멤버들인 모두 생성되고 나면 런타임에서 참조할 수 있을 텐데도, 컴파일 과정에서 아예 막혀 있습니다.
따라서 클래스 멤버에서 인스턴스 전용 키워드인 this를 사용하면 컴파일 에러가 발생합니다.
객체가 생성되지도 않았는데 객체를 참조하려 할때 발생할 수밖에 없는 런타임 null 객체 에러를 컴파일 타임에 미리 봉쇄해 버리는 거죠.
반대로 인스턴스 멤버를 초기화하는 시점에서는 이미 클래스 멤버들은 초기화가 끝나있는 상태이므로 인스턴스 멤버들은 얼마든지 클래스 멤버들을 참조할 수 있습니다. 물론 이때도 클래스 멤버는 인스턴스 멤버를 참조할 수 없습니다. (this 사용불가)
출처: https://jamescode7.tistory.com/53 [행복한 프로그래머]
정확한 자료는 없지만 앞에 링크에서 해결방안과 위의 해설로 추측을 해보자면
-> dispatherServlet에서 등록되어 있는 ApplicationConetxt에서 bean 스캐닝 의존 주입 후 클래스변수에 값주입
클래스초기화 -> 클래스변수 초기화(이때 non-static변수를 참조하고 있으면 null) -> 인스턴수 변수 초기화
이 순서로 진행되는것 같습니다.
하지만 이건 어디까지나 저의 의견이므로 참고만 하시면 좋을것 같습니다.
더 좋은 의견이 있으시면 댓글 부탁드립니다.