Spring 프레임워크의 핵심 개념이며, 스프링에서 사용하는 수많은 Bean들을 등록, 관리, 제공하는 IoC Container의 역할을 수행한다.
ApplicationContext는 BeanFactory를 상속받아 BeanFactory의 기능(Bean 관리/검색 등) 및 추가적인 기능을 정의해놓은 인터페이스이다. 실제 환경에서는 Tomcat이 Servlet Container 역할을 하는 것처럼, ApplicationContext
(의 구현체)가 Spring Container 로써 동작한다.
따라서 ApplicationContext
는 처음 스프링 애플리케이션이 실행될 때, Bean의 설정정보를 읽어오고, 이를 인스턴스화 하여 등록하며, 의존성을 주입하게된다.
앞서 말했듯이 ApplicationContext
는 인터페이스이며, 스프링으로 웹 애플리케이션을 개발할 때는 이를 확장한 WebApplicationContext
인터페이스가 사용된다. (스프링은 단순히 웹 애플리케이션만을 위한 프레임워크가 아니기 때문에 수많은 확장된 인터페이스가 존재한다)
우리가 start.spring.io 를 통해서 스프링 부트 프로젝트를 만들 때, Spring Web dependency를 추가하게 되는데, 이 안에 WebApplicationContext
가 포함되어있다.
또한, 우리가 스프링 부트를 사용할 때는 일반적으로 WebApplicationContext
의 구현체인 AnnotationConfigWebApplicationContext
클래스를 사용하게 된다. AnnotationConfigWebApplicationContext
는 어노테션 기반으로 작성된 Bean을 읽어와 Context 내부에 저장한다.
https://gowoonsori.com/spring/architecture/
스프링에서는 Context를 Root Context와 Servlet Context로 나누어 놓았다. 이 둘은 실제로 별도의 클래스로써 존재하는 것이 아니라, 계층적으로 설정을 구분해놓은 것이다.
Root Context에는 비즈니스 로직과 관련된 서비스, 레포지토리, DB 등의 설정들이 담긴다. 하지만, Root Context는 Servlet Context에 등록된 Bean을 참조할 수 없다.
Servlet Context에는 핸들러 매핑, 인터셉터, 핸들러 어댑터, 컨트롤러 등의 설정이 담기게 된다. 아까와는 반대로, Servlet Context는 Root Context에 등록된 Bean을 사용할 수 있다.
즉, Root Context에 등록되는 Bean은 모든 Context에서 사용이 가능하지만, Root Context는 자신의 Bean 이외에 다른 Context의 Bean을 사용할 수 없다.
실제로 클래스가 존재하는 것은 아니지만, 두 Context는 위처럼 부모-자식 클래스와 같은 관계를 맺고있다.
부모-자식 관계의 클래스에서 자식 클래스는 부모 클래스의 속성이나 메서드를 참조할 수 있지만, 그 반대는 불가능한 것과 같다. Servlet Context(자식)은 Root Context(부모)의 Bean을 참조해서 사용할 수 있지만, Root Context는 Servlet Context의 Bean을 사용할 수 없다.
이를 통해서, Bean의 재사용성을 증진시키고 애플리케이션의 관심사를 분리할 수 있다는 장점이 있다.
실제로는 ConfiguableWebApplicationContext에 정의된 setParent를 이용해 부모를 정의 > 일종의 의존관계를 만드는 것