IoC라는 약자로 많이 사용되는 제어의 역전(Inversion of Control)이라는 용어가 있다.
제어권의 이전을 통한 제어관계 역전
제어의 역전이라는 건, 간단히 프로그램의 제어 흐름 구조가 뒤바뀌는 것이라고 설명할 수 있다.
일반적으로 프로그램의 흐름은 main() 메서드와 같이 프로그램이 시작되는 지점에서 다음에 사용할 오브젝트를 결정하고, 결정한 오브젝트를 생성하고, 만들어진 오브젝트에 있는 메서드를 호출하고, 그 오브젝트 메서드 안에서 다음에 사용할 것을 결정하고 호출하는 식의 작업이 반복된다. 이렇게 진행되면 모든 종류의 작업을 사용하는 쪽에서 제어하는 구조이다.
제어의 역전이란 이런 제어 흐름의 개념을 거꾸로 뒤집는 것이다. 제어의 역전에서는 오브젝트가 자신이 사용할 오브젝트를 스스로 선택하지 않는다. 당연히 생성하지도 않는다. 모든 제어 권한을 자신이 아닌 다른 대상에게 위임한다.
프레임워크도 제어의 역전 개념이 적용된 대표적인 기술이다.
프레임워크는 라이브러리의 다른 이름이 아니다. 프레임워크는 단지 미리 만들어둔 반제품이나, 확장해서 사용할 수 있도록 준비된 추상 라이브러리의 집합이 아니다. 프레임워크가 어떤 것인지 이해하려면 라이브러리와 프레임워크가 어떻게 다른지 알아야한다.
라이브러리를 사용하는 애플리케이션 코드는 애플리케이션 흐름을 직접 제어한다. 단지 동작하는 중에 필요한 기능이 있을 때 능동적으로 라이브러리를 사용할 뿐이다. 반면에 프레임워크는 거꾸로 애플리케이션 코드가 프레임워크에 의해 사용된다. 보통 프레임워크 위에 개발한 클래스를 등록해두고, 프레임워크가 흐름을 주도하는 중에 개발자가 만든 애플리케이션 코드를 사용하도록 만드는 방식이다.
이제 스프링을 사용하여 스프링의 IoC를 이해해본다.
스프링의 핵심을 담당하는 건, 바로 빈 팩토리 또는 애플리케이션 컨텍스트라고 불리는 것이다.
오브젝트 팩토리를 이용한 스프링 IoC
애플리케이션 컨텍스트와 설정정보
스프링에서는 스프링이 제어권을 가지고 직접 만들고 관계를 부여하는 오브젝트를 빈(bean)이라고 부른다.
동시에 스프링 빈은 스프링 컨테이너가 생성과 관계설정, 사용 등을 제어해주는 제어의 역전이 적용된 오브젝트를 가리키는 말이다.
스프링에서는 빈의 생성과 관계설정 같은 제어를 담당하는 IoC 오브젝트를 빈 팩토리(bean factory)라고 부른다. 보통 빈 팩토리보다는 이를 좀 더 확장한 애플리케이션 컨텍스트(application context)를 주로 사용한다.
- 빈 팩토리 - 빈을 생성하고 관계를 설정하는 IoC의 기본 기능에 초점을 맞춘 것
- 애플리케이션 컨텍스트 - 애플리케이션 전반에 걸쳐 모든 구성요소의 제어 작업을 담당하는 IoC 엔진
@Configuration
public class DaoFactory {
@Bean
public UserDao userDao(){
return new UserDao(connectionMaker());
}
@Bean
public ConnectionMaker connectionMaker(){
return new DConnectionMaker();
}
}
위 코드에서 보이는 것처럼 스프링이 빈 팩토리를 위한 오브젝트 설정을 담당하는 클래스라고 인식할 수 있도록
@Configuration 어노테이션을 추가한다. 그리고 오브젝트를 만들어 주는 메서드에는 @Bean 어노테이션을 추가한다.
이제 DaoFactory를 설정정보로 사용하는 애플리케이션 컨텍스트를 만들어본다. 애플리케이션 컨텍스트는 ApplicationContext 타입의 오브젝트다. 이를 구현한 클래스는 여러 가지가 있는데 DaoFactory처럼 @Configuration이 붙은 자바 코드를 설정정보로 사용하려면 AnnotationConfigApplicationContext를 이용하면 된다.
이제 이렇게 준비된 ApplicationContext의 getBean()이라는 메서드를 이용하여 UserDao의 오브젝트를 가져올 수 있다.
public class UserDaoTest {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
ApplicationContext context = new AnnotationConfigApplicationContext(DaoFactory.class);
UserDao userDao = context.getBean("userDao", UserDao.class);
}
}
애플리케이션 컨텍스트는 ApplicationContext 인터페이스를 구현하는데, ApplicationContext는 빈 팩토리가 구현하는 BeanFactory 인터페이스를 상속했으므로 애플리케이션 컨텍스트는 일종의 빈 팩토리인 셈이다.
--> 애플리케이션 컨텍스트는 DaoFactory 클래스를 설정정보로 등록해두고 @Bean이 붙은 메서드의 이름을 가져와 빈 목록을 만들어둔다. 클라이언트가 애플리케이션 컨텍스트의 getBean() 메서드를 호출하면 자신의 빈 목록에서 요청한 이름이 있는지 찾고, 있다면 빈을 생성하는 메서드를 호출해서 오브젝트를 생성시킨 후 클라이언트에 돌려준다.
오브젝트 팩토리로 사용할 때와 애플리케이션 컨텍스트를 사용했을 때 얻을 수 있는 장점
▶ 클라이언트는 구체적인 팩토리 클래스를 알 필요가 없다.
▶ 애플리케이션 컨텍스트는 종합 IoC 서비스를 제공해준다.
- 애플리케이션 컨텍스트의 역하른 단지 오브젝트 생성과 다른 오브젝트와의 관계설정만이 전부가 아니다. 오브젝트가 만들어지는 방식, 시점과 전략을 다르게 가져갈 수도 있고, 이에 부가적으로 자동생성, 오브젝트에 대한 후처리, 정보의 조합, 설정 방식의 다변화, 인터셉팅 등 오브젝트를 효과적으로 활용할 수 있는 다양한 기능을 제공.
▶ 애플리케이션 컨텍스트는 빈을 검색하는 다양한 방법을 제공
- 애플리케이션 컨텍스트의 getBean() 메서드는 빈의 이름을 이용해 빈을 찾아준다. 타입만으로 빈을 검색하거나 특별한 어노테이션 설정이 되어 있는 빈을 찾을 수도 있다.
'Spring > 스프링의 이해와 원리' 카테고리의 다른 글
오브젝트와 의존관계 - 3. DB 커넥션 독립 / 디자인 패턴 (0) | 2022.07.13 |
---|---|
오브젝트와 의존관계 - etc. 스프링 IoC의 용어 정리 (0) | 2022.03.14 |
오브젝트와 의존관계 - 4. 개방 폐쇄 원칙 / 전략 패턴 (0) | 2022.03.14 |
오브젝트와 의존관계 - 2. 관심사의 분리 + 리팩토링 (0) | 2022.03.09 |
오브젝트와 의존관계 - 1. 스프링의 기본, 오브젝트 이해하기 (0) | 2022.03.09 |