WebApplicationContext는 ApplicationContext를 상속하고있습니다.
ServletContext에 접근할 수 있는 기능이 추가되어있습니다.
ServletContext는 ServletContainer에 의해서 만들어지며 이는 하나의 객체입니다.
여러 서블릿이 공유 가능한 정보를 ServletContext에 담습니다.
여러 서블릿이 만들어지면 개별적으로 웹 어플리케이션 컨텍스트가 만들어집니다. 모든 어플리케이션 컨텍스트에 접근이 가능한 빈?
서블릿이 서블릿 컨텍스트에 접근할 수 있듯 모든 어플리케이션 컨텍스트가 접근이 가능한 루트 어플리케이션 컨텍스트가 필요합니다.
이는 서블릿 컨텍스트가 만들어질 때 루트 어플리케이션 컨텍스트가 만들어지며 서블릿 컨텍스트에 들어있게 됩니다.
서블릿이 만든 어플리케이션 컨텍스트와 서블릿 컨텍스트에서 접근하는 어플리케이션 컨텍스트와는 부모 자식관계가 됩니다.
web.xml
스프링은 ServletContextListener를 구현한 ContextLoaderListener를 제공합니다.
ServletContextListner는 서블릿 컨텍스트의 상태가 변경될 때 호출되는 일종의 리스너입니다.
ContextLoaderListener를 통해 웹 어플리케이션 전체에서 사용 가능한 웹 어플리케이션 컨텍스트를 만듭니다. 이를 편의상 루트 어플리케이션 컨텍스트라 합니다.
코드기반

서블릿 컨테이너 안에 웹 어플리케이션이 만들어집니다.
DispatcherServlet이 요청을 받으면 WebApplicationContext에서 등록된 bean들을 가져옵니다.
WebApplicationContext에 Controller가 있으면 Controller에게 요청을 위임합니다.
요청에 관련된 여러 빈 오브젝트가 만들어지고 어댑터나 핸들러 등이 생성됩니다.
ApplicationContext.xml
web.xml

프레젠테이션 계층
서비스 계층
데이터 액세스 계층

SpringMVC모듈이 프제젠테이션 계층에 해당됩니다.
모델은 서비스계층과 데이터 엑세스 계층에 사용됩니다.
SpringJDBC모듈은 데이터 액세스 계층에 사용됩니다.
AOP는 전반적으로 사용됩니다.

디스패처 서블릿은 여러개가 만들어질 수 있습니다.
서블릿 어플리케이션 컨텍스트(디스패처 서블릿은 만들 때 전달한)에 컨트롤러를 등록하며 디스패처 서블릿이 필요한 빈들을 등록합니다.
서비스계층과 데이터 액세스 계층은 여러 서블릿이 공통으로 사용하는 영역으로 이를 루트 어플리케이션 컨텍스트로 부를 수 있습니다.
이와 같이 분리하지 않고 하나의 서블릿 어플리케이션 컨텍스트로 만들어 사용할 수 있습니다. 이 경우 루트 어플리케이션 컨텍스트는 존재하지 않으며 하나의 컨테이너에 모든 빈들이 등록된다고 볼 수 있습니다. 이러한 구조를 모놀리틱 아키텍쳐(Monolithic Architecture)라고 합니다.
최근에는 MSA(Micro Service Architecture)라는 서비스를 여러 어플리케이션으로 나눠 분산처리하는 구조가 발달하고 있습니다. 이 경우 하나의 서버가 하나의 서비스(기능)을 담당하게 됩니다. (ex. 결제, 고객, 주문 등등)
하나의 서블릿으로 하게되는 경우 서비스가 많아지게되면 컨트롤러도 많아지게되고 관리하기가 힘들어집니다. 프레젠테이션 계층만이라도 나누어 요청이 왔을때만 로드되도록 LoadOnStartUp옵션을 사용할 수 있습니다. 최초 요청에 대해 빠르게 서버를 띄울 수 있는 장점이 있습니다.
public class KdtWebApplicationInitializer implements WebApplicationInitializer {
// Spring Web MVC가 필요한 빈들이 자동으로 등록
@EnableWebMvc
@Configuration
@ComponentScan(basePackages = "org.prgms.kdt.customer",
// 컴포넌트 스캔을 할 때 컨트롤러만 추가되도록 합니다.
includeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = CustomerController.class),
// 다른 디폴트 어노테이션을 등록하지 않습니다.
useDefaultFilters = false
)
static class ServletConfig implements WebMvcConfigurer, ApplicationContextAware {...}
@Configuration
@ComponentScan(basePackages = "org.prgms.kdt.customer",
// 컴포넌트 스캔을 할 때 컨트롤러만 제외합니다.
excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = CustomerController.class)
)
@EnableTransactionManagement
static class RootConfig {...}
참고글
[Spring] root-context와 servlet-context
[Spring] ApplicationContext와 WebApplicationContext
Application-Context와 Servlet-Context
@ComponentScan의 다양한 설정들
DI(Dependency Injection)이란?