자프링 공화국의 성경. 스프링 프레임워크의 빈 생명주기를 조금 더 볼까한다.
요즘 다 스프링 부트 쓰고있으니까 SpringApplication.run() 이거 기준으로 설명하는게 제일 익숙할 거라 생각한다.
스프링 빈 생명주기를 좀더 상세히 보면
부서버 구동시 run() 메서드가 실행되며 그 메서드의 스텝을 따라 들어가면
-> createApplicationContext()
-> load(context, sources) // BeanDefinition 스캔, 파싱
-> refreshContext(context)
-> applicationContext.refresh() // 빈 생성 진입점
이후 사이클은 코드에 보이는 것과 같이
prepareRefresh -> prepareBeanFactory -> BFPP -> BPP -> 이벤트처리, 메세지소스, 리스너 등록 뭐 기타등등 으로 진행됨을 확인할 수 있다.
그럼 여기서 실제 빈을 생성해서 가져오는 곳은
finishBeanFactoryInitialization 메서드 실행부분인데
이건 도식화해서 보면
refresh()
-> finishBeanFactoryInitialization()
-> preInstantiateSingletons()
-> getBean(beanName)
-> doGetBean()
-> getSingleton(beanName, () -> createBean(...))
이런식으로 표현할 수 있다.
결국 여기서 모든 BeanDefinition 이름을 순회하면서, 조건(싱글톤 + non-lazy + non-abstract 등)을 만족하면 getBean(beanName)을 호출한다.
그럼 또 들어가서 봐야지 싱글톤은 다음에 설명하도록하고 (어떻게 프라이빗으로 생성자 폐쇄 같은거 안 해도, 싱글톤으로 컨테이너 반환하는지나 뭐 그런거 있음)
겟빈 쳐서 나오는 두겟빈 보자.
좀 길다.
mbd(빈 설정 등록된거)가 싱글턴 스코프면 람다 만들어서 createBean()를 getSingleton으로 넘긴다. (저 메서드가 싱글턴으로 구현한 구현체)
프로토타입 스코프는 그딴거없이 바로 만들어서 싱글턴반환아님 스코프 설ㅈ어하면 다른 객체로 튀어나옴(동일성 보장 x)
AbstractAutowireCapableBeanFactory 이 추상클래스는 AbstractBeanFactory를 상속한 클래스인데 여기서 실제로 구현된 createBean을 볼 수 있다.
응 ㅅㅂ 저기 또 들어가야 함 아직도 멀었음 ㅂㅅ같은거
대충 저 블럭은 Instantiate라고 하는데 인스턴스 만들기 내부에서 인스턴스 어떻게 생성할지 먼저 정한다.
아마 스프링 배울떄 DI나 주입 관련 배우면서 candidate constructors for autowiring 이런 키워드로 찾아보면 내용 나온다
다시 돌아와서 어떻게 인스턴스 만들지 결정한다음 만들고 해당 인스턴스를 래핑해서 이제서야 bean 이라는 이름의 Object로 할당한다.
근데 이것도 아직 DI건 초기화던, AOP 이딴거 하나도 안탄 raw Bean 상태임.
다음 빨간 박스 가기 전 싱크로나이즈 블럭은 대충 RootBeanDefinition 확정하는건데 메타데이터 캐싱해서 리플렉션 줄이려고 하는 곳임 대충 나도 그거밖에 모름 걍 1회용 캐시임
내려와서 박스 보면 여기는 순환참조 대응해서 싱글톤 초기 노출하는 부분임
주석 번역기 돌리면 됨
= BeanFactoryAware 같은 라이프사이클 인터페이스가 트리거해서 순환참조가 발생하는 경우도 있기 때문에, 싱글톤을 미리 캐싱해 둔다.
조건은 3개 전부 참일 경우인데
1. 싱글톤 스코프
2. 순환참조 허용 플래그
3. 해당 빈이 생성중인지 여부
그렇게되면 이제 진짜 스프링 빈 캐시등록 뭐 3단 캐시 하는 부분이 박스 내부 하단 addSingletonFactory() -> 람다고
그다음 파퓰레이션에서 DI 주입 -> 다음 초기화(initialize) 하면 니가 쓸 준비 된거다.
(니가 등록한 빈이 한참 런타임 돌다가 사라질때가 되면 destroy 트리거 잡아서 부숨)
무튼 이게 간단히본 스프링 빈 라이프사이클 앞 부분임 인텔리제이 최신버전 쯤 오면 이제 디컴파이 ㄹ아니고 소스 자체를 다운 받아줘서 보기 더 편해졌다 많이들 츄라이해 봐라.
재밌다.
화이팅이다 모두.
=====================================================
p.s. 마지막 빨간박스는 아까 얼리싱글턴 익스포저한거 랑 최종 객체랑 정합성 맞추는 부분이라 걍 뒤로 미룸
조건 분기 잘 해석해서 봐라 이해 될거다
1차 2차 3차 캐시 뭔지 알면 더 빠를건데 그냥 대충 처음에 만든거(1차확정)혹은 이미 얼리에 만들어진거(2차)에 있으면 그 만들어진걸로 정합 맞춘다가 조건의 핵심임
예외 메세지 해석
= 순환참조 과정에서 raw로 주입됐는데, 최종적으로 wrapping(프록시)이 되었다. 그래서 다른 빈들이 최종 버전을 쓰지 않는다. 이는 과도하게 eager type matching한 결과일 수 있다.
순환참조 때문에 어떤 빈들이 이 빈을 raw 버전으로 주입받았는데
최종적으로는 이 빈이 프록시로 감싸져 버리면
의존하는 빈들은 raw를 들고 있고, 컨테이너가 최종으로 노출하는 건 프록시가 되니까 일관성 꺠진다 터질게~ 이거임 그냥 몰라도 됨
그리고 이 분기까지 마치면 반환되는 익스포저는 프록시가 있으면 프록시, 없으면 얼리참조로 정렬한 객체
둘 뿐임 (raw bean 아님)
틀릴수도 있음. 필요 내용은 알아서 찾아봐라.
어우... 어렵네요
그래서 그냥 우린 @bean 딸깍하면 저렇게된다 여서 그냥 쓰면 된다. 코어 가끔 보면 재밌어. - dc App
@99.9(223.38) 그냥 예제 보고 따라치다보니까 이해를 더 못하겠더라구요. 지금은 코어는 까도 좀 이해안가서 어느정도 그래도 핵심로직까지는 보려고 하는데 쉽지는 않네요. 급하게 플젝한다고 lmax distruptor보는데 장난아니네요 ㅜ
@1일1행 잠까누찾아봤는데 스레드간 메모리 공유 보려면 가시성, volatale, CAS, atomic Class 이런거부터해서 차근처근가야할거같은데 바로 라이브러리가면 괜찮음..? 포폴 대단한거하나보네.. - dc App
@1일1행 volatile** - dc App
@99.9(58.237) 아... 좀 주제넘게? 비트코인 거래소 코어 엔진을 만들어보기로해서.. 기초가 없다보니 플젝으로 밀자 라는 느낌으로 시작했었습니다..ㅎㅎ 물론 지금은 생각이 바꼈는데 이미 하기로 해버려서 어쩔수 없더라구요 오픈소스 까보고 이런거는 쉽지않을거같아서 gpt랑 이야기하면서 하나하나 구조파고있는데 어렵네요 일단은 머리 깨져보면서 하고 끝나고 자바 공부하면서 다시 파보면 그떄가서 좀더 이해할수있지않을가 희망하고있습니다.
@99.9(58.237) 원자성이랑 cas같은 경우도 정확하게 모르고 개념? 로직정도만 아는터라
@1일1행 음 하고싶은거에 대한걸 부정할 필요는 없고 하고싶은건 해야지. 다만 취준이면 트레이드오프를 잘 생각해봐 내가 이정도 케파를 어느정도 녹여낼수 있는지. 그래서 다들 너무 크게 잡으면 말릴수도 있음. 메모리간 상태공유나 원자성, 가시성, 컴페어앤스왑 이런거 싱글톤으로 시작하면 좋음 주제는 굽삐에서 싱글톤을 배워서 만든 싱글톤이 멀티 스레딩환경에서는 깨져요! 부터 시작하면 좋음 내일 밤이나 해서 싱글톤 관련 글 하나 써볼게. 위 내용 포함된걸로. - dc App
@99.9(58.237) ㄱㅅㄱㅅ 이게 뭔가 코드를 안까보고 로직으로만 이해하니까 괴리감이 계속 생기더라구요 한번 참고해서 공부해보겠습니다!
@99.9(58.237) 궁금한게 한개있습니다. lmax 이야기하고 바로 이게 어떤개념이 필요하신지 이야기해주셧는데 어떻게 파악을하신걸가요? 이게 gpt랑 이야기하다보면 이런건 넘어가고 이야기가 계속 진행되더라구요..
@1일1행 LMAX Disruptor High Performance Inter-Thread Messaging Library version 4.0.0-SNAPSHOT 공식페이지 헤더에 인터스레드(스레드간) 메세징 라이브러리라는거보면 스레드는 프로세스의 코드, 데이터, 힙을 공유 하고 콜스택 따로인데 스레드간 메세징이면 N개의 스레드가 서로 어떤 정보를 공유 해야하니깐 원자성, 가시성이 기본으로 떠오름 그리고 링버퍼 이런개념 나오던데 저걸 도입할 예정이라면 기본적으로 어느정도 자바뿐 아닌 CS의 깊이도 필요하다고 생각하긴해 - dc App
@99.9(58.237) 아 네네 이게 lmax가 하드웨어 까지도 최적화해서 한거다보니까 l1, l2캐시 이야기랑 막 나오더라구요. 솔찍히 기본적인 cs자체도 부족해서 책하나사서 플젝하면서 해당하는부분 같이 보고 공부하면서 하면될거같네요 감사합니다! 그래도 나열해주신 정보덕에 많이 구조는 잡은거같습니다.
이게뭐야 우아
"스프링" - dc App
근데 어디까지 공부해야함
@ㅇㅇ 어디까지란건 없는데 취준이면 내가 적용한 기술이 왜 필요했는가에서 부터 접근해보셈 - dc App
저기서도 버그는 하나쯤 있어서 기여도 가능하지 않을까 라는 막연한 생각
즉시 스프링 컨트리뷰터 ㄷㄷ 깃 가보면 이슈 많더라 하나 붙잡고 공부하면 많이 배울것 같긴하더라고 - dc App
역시 스프링코어를 공부하고 기여해보는게 도움이 많이될라나
결국 필요하면 하는거라 공부방향성이 어디있는가에 따라 다른것 같음. - dc App
이걸 왜보는거임 - dc App
난 스프링이 좋거든 - dc App