웹 프로그래밍/[ Spring ]

[ Spring ] 07. Spring의 IoC Container와 Application Context 계층 구조

kim.svadoz 2021. 6. 30. 16:46
반응형

IoC Container


기본적으로 스프링의 IoC 컨테이너는 스프링 애플리케이션에서 'Object 생성', '관계 설정', '오브젝트 사용 및 제거' 등의 역할을 수행하는 컨테이너를 의미한다.

스프링에서는 '빈 팩토리', '애플리케이션 컨텍스트'라고도 하고, 아주 간단한 표현으로 Application Context 인터페이스를 구현한 클래스 오브젝트라고도 한다.

편의상 일반적으로 IoC컨테이너를 애플리케이션 컨텍스트라고 칭하고, 스프링을 개발할 때 이 애플리케이션 컨텍스트를 계층 구조로 만드는 경우가 많다.

애플리케이션 컨텍스트의 계층구조는 부모역할을 하는 root-application context(루트 애플리케이션 컨텍스트)와, servlet-applicaiton context(서블릿 애플리케이션 컨텍스트)로 구성하며 계층 구조 안에 모든 컨텍스트는 각자 독립적인 설정정보를 이용해서 Bean Object를 만들고 관리한다.

스프링 애플리케이션에서 애플리케이션 컨텍스트 계층구조를 구현할 때 사용하는 방법에는 아래와 같다.

  • root-application context
    • ContextLoaderListener 등록
    • 디폴트 설정 파일 위치가 아닌 변경시 <context-param>으로 변경
  • servlet-application context
    • DispatcherServlet 등록
    • 디폴트 설정 파일 위치가 아닌 변경시 <init-param>으로 변경

정리하자면,web.xml<context-param>에 해당하는 xml 파일에 의해 등록되는 빈은 루트 애플리케이션 컨텍스트에서 등록-관리 되는 빈이고, dispatcher-servlet.xml을 통해서 등록되는 빈은 서블릿 애플리케이션 컨텍스트에서 등록-관리되는 빈이다.

이 두 개의 IoC 컨테이너는 계층구조로 만들어진 별개의 IoC 컨테이너 인것이다.

그러면 왜 굳이 이렇게 IoC 컨테이너를 나누어서 사용하는가??

IoC 컨테이너의 종류

  • StaticApplicationContext
    • StaticApplicationContext는 코드를 통해 빈 메타정보를 등록하기 위해 사용한다.
    • 스프링의 기능에 대한 학습 테스트를 만들 때를 제외하면 실제로 사용되지 않는다.
    • 웹 관련 기능을 공부하며 학습 테스트로 검증하고 싶을 때는 StaticWebApplicationContext를 사용한다.
  • GenericApplicationContext
    • 실전에서 사용될 수 있는 모든 기능을 갖추고 있는 애플리케이션 컨텍스트이다.
    • StaticApplicationContext와 달리 xml파일과 같은 외부의 리소스에 있는 빈 설정 메타정보를 리더를 통해 읽어들여서 메타정보로 전환해 사용한다.
  • GenericXmlApplicationContext
    • GenericApplicationContext에서 XmlBeanDefinitionReader를 내장하고 있어, xml을 읽어 사용할때 편리하다.
  • WebApplicationContext
    • 스프링 애플리케이션에서 가장 많이 사용된다.
    • XML설정 파일을 사용하는 경우에는 XmlWebApplicationContext를 사용하며, 애노테이션을 사용한다면 AnnotationConfigWebApplicationContext를 사용한다.

웹 환경 애플리케이션 구조

image-20210610155159651

웹 환경에서의 스프링은 클라이언트 요청을 전부 받는 'FrontController', 'DispatcherServlet'을 제공한다.

'DispatcherServlet'은 자체적으로 Application Context를 생성하고 Root Application Context를 부모로 등록한다.

> Application Context

공통 기능을 할 수 있는 Bean 설정(DataSource, Service 등..)

각 서블릿에서 공유할 수 있는 Bean!!

  • Web Application 최상단에 위치하고 있는 Context
  • Spring ApplicationContext란 BeanFactory를 상속받고 있는 Context
  • Spring에서 root-context.xml, applicatoinContext.xml 파일은 Application Context 생성 시 필요한 설정정보를 담은 파일(Bean 선언 등..)
  • Spring에서 생성되는 Bean에 대한 IoC Container(또는 Bean Container)
  • 특정 Servlet 설정과 관계 없는 설정을 한다.(@Service, @Repository, @Configuration, @Component)
  • 서로 다른 여러 Servlet에서 공통적으로 공유해서 사용할 수 있는 Bean을 선언한다.
  • Appliction Context에 정의된 BeanServlet Context에서 정의된 Bean을 사용할 수 없다.

> Servlet Context

servlet.context.xml

Servlet 구성에 필요한 Bean 설정(Controller, Interceptor, HandlerMapping ..)

  • Servlet 단위로 생성되는 Context
  • Spring에서 servlet-context.xml 파일은 DispatcherServlet 생성 시에 필요한 설정 정보를 담은 파일
    (Interceptor, Bean생성, ViewResolver 등...)
  • URL설정이 있는 Bean을 생성(@Controller, Interceptor)
  • Application Context를 자신의 부모 Context로 사용한다.
  • Application Context와 Servlet Context에 같은 id로 된 Bean이 등록 되는 경우, Servlet Container에 선언된 Bean을 사용한다.
  • Bean 찾는 순서
    1. Servlet Context에서 먼저 찾는다.
    2. 만약 Servlet Context에서 Bean을 못 찾은 경우 Application Context에 정의된 Bean을 찾는다.
  • Servlet Context에 정의된 BeanApplication Context에서 정의된 Bean을 사용할 수 있다.

> web.xml

서블릿 클래스는 JSP와 달리 설치 뿐 만 아니라, 등록을 하는 과정이 필요로 하다.

여기서 서블릿 클래스를 등록하는 곳의 이름을 Web Application depolyment descripor(DD-deplyment Descriptor)라고 하는데 이 역할을 하는 것이 바로 web.xml이다.

web.xml파일은 웹 애플리케이션 디렉터리 마다 딱 하나씩 만 존재할 수 있다.

DD는 WAS 구동 시 /WEB-INF 디렉토리에 존재하는 web.xml을 읽어 웹 애플리케이션의 설정을 구성하기 위해 존재한다.

IoC 컨테이너 계층구조

IoC 컨테이너는 계층구조로 구현할 수 있다. 각자 독립적으로 빈을 갖고 있으며, 자신의 어플리케이션 컨텍스트에 빈이 존재하지 않을 경우, 부모 어플리케이션 컨텍스트에서 빈을 찾는다.

중요한 점은 자식 어플리케이션 컨텍스트에서는 탐색하지 않는다는 점이다.

미리 만들어진 어플리케이션 컨텍스트의 설정을 그대로 가져다가 사용하면서 그 중 일부 빈만 설정을 변경하고 싶다면, 어플리케이션 컨텍스트를 두 개 만들어서 하위 컨텍스트에서 바꾸고 싶은 빈들을 설정해줘도 된다.

일반적인 Web Application의 IoC컨테이너 구성

image-20210610155556723

image-20210610155858020

DispatcherServlet은 자체적으로 ApplicationContext를 생성하고 사용한다. 이를 ServletContext라고도 부른다.

이외에도 RootApplicationContext가 하나 존재하는데, 이는 스프링 외의 기술을 사용하는 Ajax Engine, JSP 등에서 Spring IoC의 기능을 사용할 수 있도록 하기 위함이다.

스프링 밖의 어디서라도 WebApplicationContextUtils.getWebApplicationContext(ServletContext sc) 을 호출하면 RootApplicationContext를 가져올 수 있다.

참조

https://jaehun2841.github.io/2018/10/21/2018-10-21-spring-context/#%EB%93%A4%EC%96%B4%EA%B0%80%EB%A9%B0

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=pjok1122&logNo=221744895053

반응형