스프링 기초] 컨테이너와 IoC (Inversion of Control, 제어의 역전) 란?
-
728x90
반응형
웹개발을 배우면서 항상 개념에 대한 부분이 너무 어렵고 공부를 하고 나면 까먹고 또 까먹는다.
컨테이너 또한 JAVA 기초와 함께 MVC를 배우면서 배웠으나 또 까먹었다...그런데 스프링에서도 컨테이너가 나온다.
과연 컨테이너는 뭐고 IoC랑은 어떤 상관관계가 있는지 한번 배워보겠다.
IoC == 컨테이너?
그럼 먼저 컨테이너라는 것이 무엇인지 한번 알아보자.
1. 컨테이너란??
Servlet 컨테이너, EJB 컨테이너 ... 등 기본적으로 웹개발을 배우다보면 처음에 Servlet 컨테이너라는 말로 '컨테이너' 라는 것이 익숙하게 느껴질 것이다.
컨테이너는 보통 인스턴스의 생명주기를 관리, 생성된 인스턴스들에게 추가적인 기능을 제공하도록하는 것이라고 한다.
즉, 컨테이너란 당신이 작성한 코드의 처리과정을 위임받은 독립적인 존재라고 생각하면 된다. 컨테이너는 적절한 설정만 되어 있다면 누구의 도움없이도 프로그래머가 작성한 코드를 스스로 참조한 뒤 알아서 객체의 생성과 소멸을 컨트롤해준다.
Servlet 컨테이너는 Servlet의 생성, 생성 후 초기화, 서비스 실행, 소멸에 관한 모든 권한을 가지고 있다. 개발자들이 직접 Servlet을 생성하고 서비스하지는 않는다. 이처럼 Servlet 인스턴스에 대한 생명주기를 관리하는 기능을 가진다. 또한, Servlet 컨테이너의 web.xml을 보면 JSP/Servlet 접근 권한에 대한 추가적인 서비스도 지원하고 있다. 이는 Servlet의 구현과는 별도로 각 JSP/Servlet에 대한 Security를 관리해주는 기능을 한다.
스프링 컨테이너는 스프링 프레임워크의 핵심부에 위치하며, 종속객체 주입을 이용하여 애플리케이션을 구성하는 컴포넌트들을 관리한다.
다시 말하면, 프로그래머가 작성한 코드는 컨테이너를 사용하게 됨으로서 프로그래머의 손을 떠나 컨테이너의 영역으로 떠나버리게 된다. (정확히 말하자면 컨테이너가 맘대로 객체를 생성하는 게 아니라 프로그램을 이용하는 이용자의 호출에 의해 컨테이너가 동작하게 되는 구조이다.)
*IoC/DI 컨테이너는??
스프링 프레임워크 또한 객체에 대한 생성 및 생명주기를 관리할 수 있는 기능을 제공하고 있다.
IoC 컨테이너는 객체의 생성을 책임지고, 의존성을 관리한다.
POJO의 생성, 초기화, 서비스, 소멸에 대한 권한을 가진다.
개발자들이 직접 POJO를 생성할 수 있지만 컨테이너에게 맡긴다.
*POJO (Plain Old Java Object) 란?
주로 특정 자바 모델이나 기능, 프레임워크를 따르지 않는 Java Object 를 지칭한다.
BeanFactory 계열의 인터페이스만 구현한 클래스는 단순히 컨테이너에서 객체를 생성하고 DI 를 처리해주는 기능만을 제공한다.
Bean을 등록, 생성, 조회, 반환 관리함.
팩토리 디자인 패턴을 구현 것으로 BeanFactory는 빈을 생성하고 분배하는 책임을 지는 클래스.
빈 팩토리가 빈의 정의는 즉시 로딩하는 반면, 빈 자체가 필요하게 되기 전까지는 인스턴스화를 하지 않는다.
Bean을 조회할 수 있는 getBean() 메서드가 정의되어 있음.
*책에서는 잘 사용하지 않는다고 나온다.
2) ApplicationContext
스프링을 사용하는 이유는 컨테이너 때문만이 아니라 스프링이 제공하는 다양한 부가 기능때문이다.
그렇기 때문에 ApplicationContext를 주로 사용한다.
빈팩토리와 유사한 기능을 제공하지만 좀 더 많은 기능을 제공하는 어플리케이션 컨텍스트.
Bean을 등록, 생성, 조회, 반환 관리하는 기능은 BeanFactory와 같음.
◎BeanFactory 보다 더 추가적으로 제공하는 기능
국제화가 지원되는 텍스트 메시지를 관리해 준다.
이미지같은 파일 자원을 로드할 수 있는 포괄적인 방법을 제공해준다.
리스너로 등록된 빈에게 이벤트 발생을 알려준다.
따라서 대부분의 Application에서는 BeanFactory 보다는 ApplicationContext를 사용하는 것이 좋다.
◎ 실제로 사용되는 구현 클래스
ClassPathXmlApplicationContext : 클래스패스에 위치한 xml 파일에서 컨텍스트 정의 내용을 읽어들인다.
FileSystemXmlApplicationContext : 파일 경로로 지정된 xml 파일에서 컨텍스트 정의 내용을 읽어들인다.
XmlWebApplicationContext : 웹 어플리케이션에 포함된 xml 파일에서 컨텍스트 정의 내용을 읽어들인다.
GenericXmlApplicationContext : Xml 파일을 설정 정보로 사용하는 스프링 컨테이너 구현 클래스이다. 독립형 어플리케이션을 개발할 때 사용된다.
AnnotationConfigApplicationContext : 그루비 언어로 작성된 설정 정보를 사용하는 스프링 컨테이너이다. 독립형 어플리케이션을 개발할 때 사용된다.
AnnotationConfigWebApplicationContext : 웹 어플리케이션을 개발할 때 사용하는 스프링 컨테이너로써 자바 코드를 설정 정보로 사용한다.
◎ BeanFactory 와 ApplicationContext 차이점
BeanFactory : 처음으로 getBean()이 호출된 시점에서야 해당 빈을 생성 (Lazy Loading, 게으른 호출)
ApplicationContext : 컨텍스트 초기화 시점에 모든 싱글톤 빈을 미리 로드한 후 애플리케이션 가동 후에는 Bean을 지연없이 얻을 수 있다 (미리 Bean을 생성해 놓아 빈이 필요할 때 즉시 사용할 수 있도록 보장한다.)
3. IoC의 개념
IoC (Inversion of Control, 제어권의 역전) 이라고 한다.
객체의 생성, 생명주기의 관리까지 모든 객체에 대한 제어권이 바뀌었다는 것을 의미한다.
컴포넌트 의존관계 설정 (Component dependency resolution), 설정(Configuration) 및 생명주기(LifeCyle)를 해결하기 위한 디자인 패턴(Design Pattern)
위에서 컨테이너를 설명하면서 말했던 것 처럼 기존에 자바 기반으로 어플리케이션을 개발할 때 자바 객체를 생성하고 서로간의 의존관계를 연결시키는 작업에 대한 제어권은 보통 개발되는 어플리케이션에 있었다. 그러나 Servlet, EJB등을 사용하는 경우 Servlet Container, EJB Container에게 제어권이 넘어가서 객체의 생명주기(라이프사이클)을 Container들이 전담하게 된다. 다시 한번 말해서 제어의 역전이란 인스턴스 생성부터 소멸까지의 인스턴스 생명주기 관리를 개발자가 아닌 컨테이너가 대신 해준다는 뜻이다. 즉, 컨테이너 역할을 해주는 프레임워크에게 제어하는 권한을 넘겨서 개발자의 코드가 신경 써야할 것을 줄이는 전략이다.
글로 설명하는 것은 참 어렵다.
어떠한 Library 를 사용하고 싶다고 가정한다면 개발자는 이를 사용하기 위해서 Library 를 호출 한다. 즉 주도권 자체가 개발자가 쥐고 있는 상태이다. 반면 SpringFrameWork 에서 IoC는 프레임워크 내에 라이브러리가 구성되어 있고 프레임워크에서 개발자가 작성한 코드를 호출하기 때문에 주도권이 프레임워크에 있는 것이다.
4. IoC와 DI의 관계
스프링 프레임워크의 가장 큰 장점으로 IoC 컨테이너 기능이 부각되어 있으나, IoC 기능은 스프링 프레임워크가 탄생하기 훨씬 이전부터 사용되던 개념이었다. 그러므로 "IoC 기능을 스프링 프레임워크의 장점이라고 이야기하는 것은 적합하지 않다"고 반론을 제기하면서 "새로운 개념을 사용하는 것이 적합하다"고 주장한 사람이 마틴 파울러이다. 경량 컨테이너들이 이야기하는 IoC를 DI라는 용어로 사용하는 것이 더 적합하다고 이야기하고 있다. 마틴 파울러의 이 같은 구분 이후 IoC 개념을 개발자들마다 다양한 방식으로 분류하고 있으나 다음 그림과 같이 IoC와 DI 간의 관계를 분류하는 것이 일반적이다.
5. 기타
자바빈 vs 스프링 빈
자바 빈:데이터를 표현하는 것을 목적으로 하는 자바클래스이다. 컴포넌트와 비슷한 의미로 사용되기도 한다.
클래스에는 값을 저장하는 속성필드, get,set 메소드, 기본 생성자등을 포함하고 있다.
+) java.io.Serializable 인터페이스는 생략 가능하나 빈즈 규약에 명시된 내용으로 자바 빈즈에 저장된 프로퍼티를 포함한 채로 파일 시스템에 저장되거나 네트워크로 전송될 수 있도록 객체 직렬화를 제공해야 하므로 implements 한다.