Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save taekwon-dev/40f87913e2c6bcdd976ffc33ae132583 to your computer and use it in GitHub Desktop.
Save taekwon-dev/40f87913e2c6bcdd976ffc33ae132583 to your computer and use it in GitHub Desktop.

[Spring MVC] How Spring MVC works (1) - WebApplicationContext, Context Hierarchy

Spring 에서 제공하는 서블릿 기반의 웹 프레젠테이션 계층 프레임워크가 Spring MVC 다.
How Spring MVC works 를 주제로 두 개의 글로 나눠서 정리할 예정이고, 첫 번째 글인 이번 글에서는 WebApplicationContext , Context Hierarchy 중심으로 스프링 애플리케이션이 웹 환경에서 스프링 컨테이너가 어떻게 구성되는 지를 다룰 예정이다.


🐢 WebApplicationContext

Spring 에서는 웹 환경에서 사용하기 위해 IoC Container 중 하나인 WebApplicationContext 를 제공하면서 의도적으로 웹 애플리케이션의 컨텍스트를 두 가지로 분리했다.

image [ 그림 1 ]

[ 그림 1 ] 은 Spring MVC 공식 문서에서 제공한 자료인데, 앞서 언급한 두 가지 애플리케이션 컨텍스트를 볼 수 있다. 웹 애플리케이션 컨텍스트를 두 가지로 분리한 이유는 토비의 스프링에서 다음과 같이 설명한다.

이렇게 스프링 컨텍스트를 두 가지로 분리해둔 이유는 스프링 웹 서블릿 컨텍스트를 통째로 다른 기술로 다른 기술로 대체할 수 있도록 하기 위해서다.

스프링 웹 서블릿 컨텍스트를 통째로 다른 기술로 대체하는 것과 스프링 컨텍스트를 분리하는 것이 어떤 의미가 있을까?

[ 그림 1 ] 을 통해 Servlet WebApplicationContext 의 특징을 한 번 찾아보자.

  • Servlet Web Application 컴포넌트 (Controller, ViewResolver, HandlerMapping)를 저장한다.
  • Root WebApplicationContext에 의존한다.

Servlet WebApplicationContext 는 이름 그대로, 서블릿 기반의 웹 애플리케이션의 컴포넌트를 관리하기 위한 컨테이너 역할을 담당한다. 만약 서블릿 기반의 웹 애플리케이션이 아닌 경우에는 별도의 다른 컨텍스트가 필요할 것이다. 즉, Servlet WebApplicationContext 는 웹 계층 기술이 대체될 경우 더 이상 사용하지 않는 대상이 될 수 있다는 것이다.

반면, Root WebApplicationContext 는 서비스, 데이터 액세스 계층을 담고 있고 이는 웹 계층 기술의 종류와 상관 없이 웹 계층에서 의존하는 대상이다.

image [ 그림 2 ]

정리하자면, 웹 계층의 기술이 다른 기술로 대체 되어도 웹 계층에서 (심지어 스프링에서 제공하지 않는 웹 계층 기술이어도) 스프링 기술이 적용된 서비스, 데이터 액세스 계층에 접근하는 구조를 일관성있게 만들기 위해 스프링 컨텍스트를 두 가지로 분리했다고 이해할 수 있다.


🐢 Context Hierarchy

image [ 그림 3 ]

[ 그림 3 ] 에서 Delegates if no bean found 는 어떤 맥락에서 나온 것일까? 결론부터 말하면 Container Hierarchy 에서 나온 내용이다. 토비의 스프링에서 Context Hierarchjy 가 필요한 상황을 아래와 같이 설명한다.

빈을 담아둘 IoC 컨테이너는 애플리케이션마다 하나씩이면 충분하다. 빈의 개수가 많아져서 설정파일이 커지는 게 문제라면 파일을 여러 개로 쪼개서 만들고 하나의 애플리케이션 컨텍스트가 여러 개의 설정 파일을 사용하게 하면 그만이다. 하지만 한 개 이상의 IoC 컨테이너를 만들어두고 사용해야 할 경우가 있다. 바로 트리 모양의 계층구조를 만들 때다.

여기서 말하는 트리 모양의 계층구조 는 이미 우리가 위에서 다룬
Servlet WebApplicationContext , Root WebApplicationContext 관계를 통해서 확인 했다.

image [ 그림 4 ]

트리 구조의 계층을 생각 했을 때 [ 그림 4 ] 를 예로 들 수 있다. 각각의 컨텍스트는 별도의 독립적인 설정 정보를 기반으로 빈 오브젝트를 생성하고 관리하는데, DI를 위해서 빈을 검색 할 때는 검색 범위를 부모 애플리케이션 컨텍스트까지 넓힌다. 가장 먼저 자신이 관리하는 컨텍스트에서 찾고 대상 빈 오브젝트가 있는 경우에는 검색을 멈춘다. 하지만 자신이 관리하는 컨텍스트 내에 찾는 빈이 없는 경우에는 부모 애플리케이션 컨텍스트에 요청을 한다. 단, 루트 애플리케이션 컨텍스트까지 빈 검색을 요청했음에도 찾지 못한 경우에는 검색을 중단한다.

Delegates if no bean found 를 찾는 빈이 없는 경우 루트 애플리케이션 컨텍스트에 요청을 보내는 것으로 이해할 수 있다. 근데 Context Hierarchy 를 사용하는 이유가 뭘까? 토비의 스프링에서 계층 구조를 사용하는 이유를 아래와 같이 설명한다.

  1. 미리 만들어진 애플리케이션 컨텍스트의 설정을 그대로 가져다가 사용하면서 그중 일부 빈만 설정을 변경하고 싶다면, 애플리케이션 컨텍스트를 두 개 만들어서 하위 컨텍스트에서 바꾸고 싶은 빈들을 다시 설정해줘도 된다. 이렇게 기존 설정을 수정하지 않고 사용하지만 일부 빈 구성을 바꾸고 싶을 경우, 애플리케이션 컨텍스트의 계층구조를 만드는 방법이 편리하다.

  2. 애플리케이션 안에 성격이 다른 설정을 분리해서 두 개 이상의 컨텍스트를 구성하면서 각 컨텍스트가 공유하고 싶은게 있을 때 계층구조를 이용한다.

위에서 언급한 이유 중 2)Servlet WebApplicationContext , Root WebApplicationContext 관계가 계층구조로 구성된 이유를 설명한다.

[ 그림 1 ] 을 보면, DispatcherServlet 내부에 두 컨텍스트가 모두 포함되어 있는 것 처럼 묘사됐지만 사실 DispatcherServlet 즉, 서블릿 레벨에서는 Servlet WebApplicationContext 를 관리하고, 애플리케이션 레벨에서 Root WebApplicationContext 를 관리한다. 하나의 웹 애플리케이션에서 DispatcherServlet 는 두 개 이상 존재할 수 있는데, 이 때 각 DispatcherServlet 별로 독립된 WebApplicationContext 를 생성해서 관리한다.

image [ 그림 5 ]

DispatcherSevlet 이 두 개 일 때 [ 그림 5 ] 와 같이 표현될 수 있고, 이 때 계층 구조를 활용해서 공유 자원은 Root WebApplicationContext 에서 관리해서 각각의 Servlet WebApplicationContext 에서 활용할 수 있도록 할 수 있다. (계층 구조를 이용하는 이유)

하지만, [ 그림 1 ] 에서 표현된 것 처럼 일반적으로 DispatcherServlet 하나만 운용한다. DispatcherServlet 이 하나만 있어도 모든 요청을 처리할 수 있기 때문이다. 그러면 계층 구조를 사용할 의미가 없지 않은가? 계층 구조를 왜 사용하지? 라는 생각을 할 수 있다.

이 질문에 대한 답을 토비의 스프링에서는 다음과 같이 설명한다.

그 이유는 전체 애플리케이션에서 웹 기술에 의존적인 부분과 그렇지 않은 부분을 구분하기 위해서다. 스프링을 이용하는 웹 애플리케이션이라고 해서 반드시 스프링이 제공하는 웹 기술을 사용해야 하는 것은 아니다. 데이터 액세스 계층이나 서비스 계층은 스프링 기술을 사용하고 스프링 빈으로 만들지만 웹을 담당하는 프레젠테이션 계층은 스프링 외의 기술을 사용하는 경우도 종종 있기 때문이다.


스프링 웹 애플리케이션이 어떻게 스프링 컨테이너를 구성하고 사용하는 지에 대해서 큰 틀에서 알아봤다. 다음 글에서는 Spring MVC 핵심 요소인 DispatcherServlet 을 중심으로 Spring MVC 구성하는 컴포넌트 및 내부 동작 원리에 대해서 다뤄볼 예정이다.


| Reference

토비의 스프링 Vol. 1 | 1.4 제어의 역전 (IoC) 토비의 스프링 Vol. 2 | 1.5 스프링의 IoC 토비의 스프링 Vol. 2 | 1.1 IoC 컨테이너: 빈 팩토리와 애플리케이션 컨텍스트 Web on Servlet Stack
Tomcat, Spring MVC의 동작 과정

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment