스프링 프레임워크의 핵심적인 개념에는 IoC Container, Dependency Injection 등이 있다. Dependency Injection(의존성 주입)은 지난 포스트에서도 몇 번 다뤄봤으니 이번에는 IoC Container, 즉 제어 역전(inversion of control) 컨테이너에 대해 조금 더 조사해보았다.
제어 역전(Inversion of Control, IOC)
제어 역전이라는 것은 의존성 주입과는 다르다. 의존성 주입이 결합도를 낮춰서 프로그램을 좀 더 유연하게 구축하고자 하기 위한 거라면 제어 역전은 소스 코드의 제어를 컨테이너나 프레임워크에 이전하는 소프트웨어 공학 기법이다. 이게 무슨 말이냐면 스프링 프레임워크에서 의존 자동 주입(@Autowired 등)을 할 때 이 의존성을 누가 주입해주는가? 누가 Bean 객체를 생성해서 의존하는 곳에 적절하게 주입해주는가? 바로 코드를 작성하는 우리가 아니라 스프링 프레임워크다.
프레임워크와 라이브러리의 차이점은 다른 포스트에서도 많이 설명되어 있기 때문에 굳이 나열하지 않겠지만 코드의 방향성에 차이가 있다. 즉 정방향, 내가 코드를 호출하느냐, 아니면 역방향, 내 코드가 호출되느냐의 차이인데 라이브러리를 한 번이라도 사용해 봤다면 알겠지만 다른 사람이 배포한 라이브러리를 사용할 때는 그냥 해당 라이브러리에 정의된 클래스나 함수를 호출해서 사용하면 된다.
하지만 프레임워크는 어떨까? 이번 스프링 프레임워크에서도 그렇지만 의존 자동 주입 같은 기능은 프레임워크 사용자가 따로 구현하지 않는다. 대신 미리 구현된 프레임워크의 코드에서 사용자가 작성한 코드를 가지고 실행시켜서 애플리케이션 작업을 수행한다. 이렇게 코드의 제어가 코드를 작성한 개발자에서 프레임워크로 역전된 것을 제어 역전(Inversion of Control)이라 하며 스프링 프레임워크는 이 개념을 활용하고 있다.
이런 제어 역전의 장점은 프로그램의 실행(프레임워크)과 구현(개발자) 자체를 분리하고 프로그램을 모듈화 하거나 컴포넌트들을 분리하고 가짜 의존 대상(mock)을 활용하여 프로그램 테스트를 쉽게 수행할 수 있다는 점이 있다. 이를 구현할 수 있는 방법 중 하나가 Dependency Injection, 즉 의존성 주입인 것이다.
컨테이너(Container)
스프링 프레임워크에서는 컨테이너(IoC Container)가 Bean 객체를 생성, 설정하고 적절한 곳에 주입하며 소멸할 때까지 생명 주기 동안 관리한다. 이 컨테이너는 지난 포스트에서 언급한 ApplicationContext, BeanFactory 인터페이스를 구현한 여러 클래스로 제공되며 각자 다른 방법으로 설정 파일(configuration metadata)을 읽어 Bean 객체들을 등록한다. 여기에 의존성 주입 기술을 활용하여 애플리케이션을 구성하는 컴포넌트들을 관리(Bean 객체를 생성, 주입, 생명주기 관리 등)하는 것이다.
언급했듯이 ApplicationContext는 BeanFactory 인터페이스의 기능들을 대부분 포함하며 기업 친화적(enterprise-specific)인 기능들을 많이 갖추고 있다. 그에 비해 BeanFactory 인터페이스는 의존성 주입을 위한 기본적인 기능들만 갖추고 있기 때문에 대부분 ApplicationContext를 사용한다고 한다. BeanFactory 관련 인터페이스들은 현재로써는 호환성(backward compatibility)을 위해 남아있는 상태라고 한다.
즉 IoC Container, 즉 제어 역전 컨테이너라는 것은 이 Bean 객체들을 설정 파일에서 읽어서 관리하고 사용자 대신 프레임워크 측면에서 이 객체들을 생성하거나 주입하는 컨테이너라 할 수 있을 것이다.
[참고 | medium.com/lifeinhurry/what-is-spring-container-spring-core-9f6755966fe9]
[참고 | www.baeldung.com/inversion-control-and-dependency-injection-in-spring]
[참고 | www.tutorialspoint.com/spring/spring_ioc_containers.htm]
'Spring 프레임워크 > 이론' 카테고리의 다른 글
Spring의 빈 범위(Bean Scope) (0) | 2021.02.23 |
---|---|
Spring의 빈 생명주기(Bean Lifecycle) (0) | 2021.02.22 |
Spring의 컴포넌트 스캔(Component Scan) (0) | 2021.02.21 |
Spring의 의존 자동 주입(@Autowired) (0) | 2021.02.21 |
Spring의 의존성 주입(Dependency Injection) (0) | 2021.02.14 |