Web/Spring

스프링 컨테이너

mayleaf 2023. 1. 24. 22:48

기존에 사용했던 Nest.js와 Flutter 에서 의존관계를 관리했던 방법

Nest.js를 쓰거나 Flutter 로 어플리케이션 개발을 할때는 DI를 구현해서 사용했다.

Flutter 로 DI를 구현해서 사용했을때에는 Service Locator라는 라이브러리를 사용해서 어플리케이션 실행 시점에 ServiceLocatorInitializer(가칭)에서 의존관계를 조립해서 모든 의존관계를 ServiceLocator에 주입해두고 꺼내서 썼다. 어디에서 어떻게 의존관계가 관리되는지는 명확했다.

Nest.js를 쓸때는 초기화된 결과들이 저장되는 곳은 몰라도, @Module을 통해서 어떤 모듈이 서로 참조하고, 노출되는 Provider는 어떤것이 있는지 알 수 있었다.

스프링은 어떻게 의존관계를 관리하지? 내가 궁금했던 점

스프링을 처음 접했을때 스프링부트와 스프링을 동시에 접하면서 ApplicationContext에 대한 개념이 없이 스프링을 사용했다. @Service , @Repository같은 @Component를 포함한 어노테이션들을 쓰면 스프링에서 해당 객체를 위한 의존관계를 관리해준다는 것까지만 알고, 이것들이 어떻게 어떤 순서로 조립되는지는 몰랐다. 그래서 누가 순서대로 객체를 초기화해주고, 생성된 객체는 어디에서 관리가 되지? 싱글톤으로 컴포넌트들이 관리가 된다면 그걸 들고 있는 코드는 어디에 있는걸까?

 

스프링 컨테이너에 의존관계가 저장된다. 그리고 싱글톤으로 만드는 것은 CGLib에서 바이트코드 조작을 통해서 한다. 

오늘 ApplicationContext를 알게 되면서 여기에 해당 의존관계들이 저장된다는 것을 배웠다.

정확히는 BeanFactory가 해당 내용을 담당하지만, 거의 ApplicationContext를 사용하니 그냥 ApplicationContext라고 하겠다.

스프링 컨테이너에 스프링 빈들이 등록되는건 여러가지 방식을 통해서 사용될 수 있다. Annotation, XML, 사용자 정의된 파일을 통해서 할 수 있다. 이 중에서 Annotation을 사용해서 ApplicationContext를 사용하면 위에서 언급한 플러터에서의 방식과 굉장히 유사하게 의존관계를 관리하는 것을 확인할 수 있다.

Flutter에서 사용했던 방법과 다르게, BeanDefinition을 파악하고 주입을 해주는 것은 스프링에서 직접 해주지만 AppConfig를 보면서 "결국 코드로 어딘가에서 관리될 것 같은데 그게 안보이네" 했던 궁금증이 해결되었다