Applicaiton Context에 들어가기 전에 먼저 IoC, DI에 대한 내용을 알아야 한다.
제어의 역전 간단히 말해 스프링 컨테이너(빈 팩토리, 애플리케이션 컨텍스트)가 객체를 관리, 제공하는 역할을 한다.
이것을 IoC(Inversion of Control)이라고 하며 직접 객체를 생성하는 것이 아닌 외부에서 관리하는 객체를 가져와 사용하는 것을 말한다.
Dependency Injection 의존성 주입
간단히 설명하면 어떤 클래스가 다른 클래스에 의존한다는 뜻이다. 스프링에서 @Autowired는 스프링 컨테이너에 있는 빈이라는 것을 주입하는 역할을 한다. 빈은 쉽게 말해 스프링 컨테이너에서 관리하는 객체를 말한다.
스프링에서 IoC를 담당하는 컨테이너를 빈 팩토리, 애플리케이션 컨텍스트, 스프링 컨테이너라고 한다.
스프링 컨테이너는 DI 작업보다 더 많은 일을 하고 이에 해당하는 필요한 여러가지 컨테이너 기능을 추가한 것을 애플리케이션 컨텍스트(Application Context)라고 한다.
애플리케이션 컨텍스트가 스프링 애플리케이션을 만들기 위해 어떤 일을 하는지를 보자.
POJO 클래스라는 것은 객체지향적인 원리에 충실하면서, 환경과 기술에 종속되지 않고 필요에 따라 재활용 될 수 있는 방식으로 설계된 오브젝트를 말한다.
POJO 클래스들 중에 애플리케이션에서 사용할 것을 선정하고 이를 IoC 컨테이너가 제어할 수 있도록 적절한 메타정보를 만들어 제공하는 작업이다.
설정 메타 정보는 빈을 어떻게 만들고 동작할 것인가에 대한 정보이다.
단어 그대로 스프링 빈의 설정 메타 정보이다.
각 @Bean, 당 각 하나씩 메타 정보가 생성된다.
스프링 컨테이너는 이 메타 정보를 기반으로 스프링 빈을 생성한다.
스프링 메타 정보는 BeanDefinition 인터페이스로 표현되는 추상 정보다.
애플리케이션 컨텍스트는 이 BeanDefinition으로 만들어진 메타 정보를 담은 오브젝트를 사용해서 IoC와 DI작업을 수행한다고 합니다.
스프링 IoC 컨테이너는 각 빈에대한 정보를 담은 설정 메타정보를 읽어들인 뒤, 이를 참고해서 빈 오브젝트를 생성하고 프로터티나 생성자를 통해 의존 오브젝트를 주입해주는 DI 작업을 수행합니다.
이 작업을 통해 만들어지고, DI로 연결되는 오브젝트들이 모여서 하나의 애플리케이션을 구성하고 동작하게 되는데 이것이 IoC 컨테이너(Applicaiton Context)의 역할이 됩니다.
![]()
결국 스프링 애플리케이션이란 POJO 클래스와 설정 메타정보를 이용해서 IoC 컨테이너(Application Context)가 만들어주는 오브젝트의 조합이다.
간단히 말해 ApplicationContext를 확장한 인터페이스다.
이 WebApplicationContext를 구현한 구현체들이 스프링 애플리케이션에서 가장 많이 사용된다.
구현체는 Xml 설정파일을 사용하는 XmlWebApplicationContext, 애너테이션 기반의 설정 리소스를 사용하는 AnnotationConfigWebApplicationContext등이 있다.
WebApplicationContext를 사용법을 알려면 IoC 컨테이너를 적용했을때 애플리케이션을 기동시키는 방법에 대해서 알아야 한다.
Bean 설정 메타 정보를 이용해서 Bean 오브젝트를 만들고 DI 작업을 수행하지만 그것만으로 애플리케이션이 동작하지는 않다.
자바 애플리케이션 main() 메서드처럼 어디선가 특정 Bean 오브젝트의 메서드를 호출함으로써 애플리케이션이 동작이 된다.
이런 기동시키는 역할을 맡은 Bean을 사용할려면 IoC 컨테이너에서 요청해서 Bean 오브젝트를 가져와야되고 만약 직접 IoC 컨테이너를 셋업했다면 다음과 같은 코드가 등장한다.
![]()
적어도 한 번은 IoC 컨테이너에게 요청하면 Bean 객체를 가져오고 이때 getBean()을 사용해서 ApplicationContext안에 있는 객체를 가져온다.
그 이후에는 빈 객체끼리 DI로 서로 연결 되어 있어 의존관계를 타고 필요한 객체가 호출하면서 애플리케이션이 동작이 된다.
hello.print()를 호출했으면 더 이상 컨테이너의 도움을 받지 않고도 컨테이너 안에 구성된 빈 객체에 의해 애플리케이션이 동작한다
IoC 컨테이너의 역할은 이렇게 초기에 빈 객체를 생성하고 DI한 후 최초로 애플리케이션을 기동할 빈을 제공해주는 것 까지이다.
그런데 웹 애플리케이션은 동작하는 방법이 다르다. 웹에서는 main() 메서드를 호출할 방법이 없다. 그래서 웹 환경에서는 main() 메서드 대신 서블릿 컨테이너가 브라우저로부터 오는 HTTP 요청을 받아서 해당 요청에 매핑되어 있는 서블릿을 실행시켜주는 방식으로 동작한다. 서블릿이 일종의 main()의 역할을 하는 셈이다.
![]()
main() 역할을 하는 서블릿을 만들어두고, 미리 애플리케이션 컨텍스트를 생성해둔 다음, 요청이 서블릿으로 들어 올 때마다 getBean()으로 필요한 빈을 가져와서 정해진 메서드를 실행시키면 된다.
단지 main()가 해줬던 작업을 웹 애플리케이션에 소속된 서블릿이 대신 해줄 뿐이다.
서블릿 컨테이너는 사용자의 요청을 받아서 서블릿을 동작시키는 일을 맡는다.
서블릿은 웹 애플리케이션이 시작될 때 미리 만들어둔 웹 애플리케이션 컨텍스트에게 빈 객체로 구성된 애플리케이션의 기동 역할을 해줄 빈을 요청해서 받아두고 미리 지정된 메서드를 호출함으로써 스프링 컨테이너가 DI방식으로 구성해둔 애플리케이션 기능이 시작되는 것이다.