[Boostcourse] 풀스택/웹 프로그래밍(풀스택)

Spring Core : 개요 { 컨테이너, IoC, DI, BeanFactory, ApplicationContext }

Ben의 프로그램 2023. 7. 20. 19:59
728x90
컨테이너 란?
컨테이너는 인스턴스의 생명주기를 관리한다. 인스턴스를 직접 생성해서 실행하고 인스턴스가 소멸되는 과정을 우리가 직접 하지 않고 누군가가 대신 해주는 것을 컨테이너라고 하는데요. 에를 들어 서블릿 공부했었을 때 서블릿 클래스를 정의하긴 했지만 서블릿을 인스턴스화 하는 과정을 직접 하지는 않았습니다. 그 일을 사실은 Tomcat 이 대신 해주고 있었는데요. WAS 는 서블릿 컨테이너를 가지고 있다는 것을 의미니다. WAS는 웹 브라우저로부터 서블릿에 대한 요청을 받으면 서블릿을 메모리에 올린 다음에 실행을 하게 됩니다. 개발자가 서블릿 클래스를 작성했지만 실제로 메모리에 올리고 실행하는 것은 WAS 가 가지고 있는 서블릿 컨테이너가 해주고 있는 겁니다. 서블릿 컨테이너는 동일한 서블릿에 대한 요청을 받으면 또 메모리에 올리지 않고 기존에 메모리에 올라가있던 서블릿을 실행해서 그 결과를 웹 브라우저에게 전달하는 역할을 합니다. JSP 파일도 마찬가지였습니다. JSP 파일을 생성하긴 했지만 JSP가 서블릿으로 바뀌고 서블릿이 실행되고 인스턴스가 생성되는 과정이 진행이 되었는데요. 그 부분도 우리가 직접 하지 않고 Tomcat 이라는 WAS 가 대신 실행했었습니다. 아무튼 이렇게 인스턴스의 생명주기를 관리해주는 것을 컨테이너라고 합니다. 

생성된 인스턴스들에게 추가적인 기능을 제공하기도 합니다.

 

 

IoC 란?
IoC 란 Inversion of Control 의 약어이다. inversion 은 사전적 의미로는 '도치, 역전'을 의미한다. 그래서 보통 IoC를 '제어의 역전'이라고 번역한다. 개발자는 프로그램의 흐름을 제어하는 코드를 작성한다. 그런데, 이 흐름의 제어를 개발자가 하는 것이 아니라 다른 프로그램이 그 흐름을 제어하는 것을 IoC라고 말한다.

말이 어려운데 예시와 함꼐 이해해보도록 하겠습니다. 기본적으로 IoC 에서 말하는 제어라는 것은 인터페이스와 깊게 연관이 있습니다. 인터페이스를 사용하면 인터페이스를 구현한 클래스들이 어떤 멤버를 갖고 있다는 것을 확신할 수 있는데요. 인터페이스를 구현한 클래스들을 사용하려면 구현체, 즉 인스턴스를 생성해서 사용해야 합니다. 그런데, 우리는 이런 고민을 하게 되는거죠. 인터페이스 너무 유용하고 좋은데, 클래스들의 객체 생성을 일일이 필요할 때마다 지정을 해야하는데, 이것을 어떻게 하면 코드의 변경없이 자동으로 되게 할 수 있을까? 이런 고민 끝에 나온 것이 클래스 생성 공장을 만드는 것이었습니다. 클래스들의 생성을 맡아서 하는 한 클래스를 생성하는 거에요. 그리고 그 클래스의 멤버 함수를 통해서 클래스 생성을 진행하는 거죠. 그런데, 여기서도 사람들은 불편함을 느꼈습니다. 다 좋은데, 클래스를 생성하는 공장을 직접 만드는 것 조차 싫은거죠. 다른 클래스나 새로운 클래스를 만들어야 한다면 새로운 공장도 직접 만들어줘야 했으니까요. 스프링이 이 일을 대신 해주는 것이죠. 스프링의 빈 같은 것들이 공장의 역할을 대신해주고 있습니다. 

 

DI 란?
클래스 생성 공장들이 인스턴스를 만들었다면 실제로 그것들을 사용해야 합니다. 사용하기 위해서는 생성된 객체를 받아와야겠죠. 공장이 생성해준 객체들을 받아올 때는 어떻게 사용할 것인가가 중요한데요. DI (Dependency Injection) 가 공장에서 생성된 클래스들을 주입받는 방법 중에 하나입니다. 

DI 는 클래스 생성 공장에서 생성된 인스턴스들을 주입받는 방법입니다. Dependency Injection 의 약자로, 의존성 주입이라는 뜻을 가지고 있습니다. DI 는 클래스 사이의 의존 관계를 빈(Bean) 설정 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것을 말한다

 

DI 예시
Dependency Injection 의 예시를 보겠습니다. 우선 DI 가 적용되지 않은 경우입니다. 

new 키워드를 사용해서 직접 인스턴스를 생성해서 사용하고 있는 것을 볼 수 있습니다. 이번에는 DI 가 적용된 예시를 보겠습니다. 

Spring 에서는 인스턴스를 만드는 주체가 바뀌었습니다. IoC가 발생한 것이죠. 개발자가 작성한 코드에는 어디에도 new 키워드가 없는 것을 확인할 수 있습니다. 약속된 Annotation 들을 활용하여 여러분들은 선언만 해주면 Spring 컨테이너가 인스턴스를 생성한 다음 인스턴스를 내가 원하는 곳에 주입해줍니다. 그래서 우리는 바로 생성된 인스턴스를 사용하기만 하면 되는 것이죠. 굉장히 편리합니다. 이제 개발자가 클래스를 사용하기 위해서 메모리에 올리지 않아도 대신 처리해주는 것이죠. 어색할 수 있는데요. 사실은 굉장히 익숙한 것이기도 합니다. 우리가 이전에 Servlet 을 사용했을 때 new 키워드를 통해서 클래스를 생성한 다음 사용하지 않았는데요. WAS 가 우리 대신(IoC) 인스턴스를 생성하여 메모리에 올려주었던 것이죠. 

 

 

Spring 에서 제공하는 IoC / DI 컨테이너 : BeanFactory , ApplicationContext
스프링이 가지고 있는 클래스 생성 공장에는 대표적으로 2개가 있습니다. IoC/DI 컨테이너는 스프링 전반에서 사용됩니다. 따라서 잘 이해하고 사용하는 것이 중요하다고 할 수 있습니다. 우선 여기서는 간단하게 알아보고 다음 강의에서 실제로 어떻게 사용되는지 알아보도록 하겠습니다.

[ BeanFactory ]
IoC/DI 에 대한 아주 기본적인 기능만 가진 공장입니다. 

[ ApplicationContext ]
BeanFactory의 모든 기능을 포함하며, 일반적으로 BeanFactory보다 추천된다(BeanFactory는 너무 간단하기 때문이다). ApplicationContext 는 BeanFactory 의 모든 기능 뿐만 아니라 트랜잭션처리, AOP 등에 대한 처리를 할 수 있습니다. BeanPostProcessor, BeanFacotryPostProcessor 등을 자동으로 등록해줍니다. BenaPostProcessor 는 컨테이너의 기본 로직을 오버라이드해서 인스턴스화와 의존성 처리 로직을 개발자가 원하는대로 구현을 할 수 있게 해줍니다. BeanFactoryPostProcessor 는 설정 메타 데이터를 커스터마이징할 수 있는 부분입니다. 이런 것을 사용하면 공장에서 객체를 만드는데 개발자가 원하는 방향으로 만들게 됩니다. 그 외에도 국제화 처리, 어플리케이션 이벤트 등을 처리할 수 있습니다. 

 

 

출처 : boostcourse 웹 프로그래밍(풀스택) 
https://www.boostcourse.org/web316/lecture/20655?isDesc=false