본문 바로가기
백엔드

[Spring] IoC와 DI - 2. IoC(제어의 역전)이란? (토비의 스프링)

by BeforB 2021. 9. 26.
728x90

 

 

이전 글 - [Spring] IoC와 DI - 1. 오브젝트와 의존관계(토비의 스프링)

관련 글 - [Spring] Bean Factory와 Application Context

 

[Spring] Bean Factory와 Application Context

IoC와 DI에 대해서 깊게 파보려니 역시 Bean과 BeanFactory, ApplicationContext에 대해 한 번쯤 깊게 알아봐야 할 것 같아서 정리해보려고 한다. 다른 사람들이 정리해놓은 글만 읽었을 때는 아무리 읽어도

beforb.tistory.com

 

[Spring] IoC와 DI - 1. 오브젝트와 의존관계(토비의 스프링)

목차 스프링이란? 1.1. 스프링의 핵심 프로그래밍 모델 오브젝트와 의존 관계 2.1. 상속을 통한 확장 2.2. 오브젝트 2.3. 관계설정 책임의 분리 용어 정리 포스팅을 시작하며.. SSAFY에서 2학기 프로젝

beforb.tistory.com

 

 

 

 

시작에 앞서..

- 팩토리 : 객체의 생성 방법을 결정하고 그렇게 만들어진 오브젝트를 돌려주는 역할을 하는 오브젝트를 팩토리라고 부른다.

               * 디자인패턴에서의 팩토리와는 역할이 다르니 혼동하지 않도록 주의하자.

 

이전 예제에서 UserDaoTest는 원래의 역할인 UserDao의 테스트 기능 말고도 기존에 UserDao가 가지고 있던 기능인ConnectionMaker의 구현 클래스를 사용할지 결정하는 기능을 추가로 떠맡았다. 이 기능을 분리하는 역할을 맡을 클래스를 DaoFactory라고 하고 UserDaoTest에 담겨있던 UserDao와 ConnectionMaker 관련 생성 작업을 DaoFactory로 옮기자.

DaoFactory의 userDao 메소드를 호출하면 DConnectionMaker를 사용하여 DB커넥션을 가져오도록 이미 설정된 UserDao 오브젝트를 돌려준다.

package springbook.user.dao;

public class DaoFactory {
  public UserDao userDao() {
    // 팩토리의 메소드는 UserDao 타입의 오브젝트를 어떻게 만들고 어떻게 준비시킬지를 결정한다.
    ConnectionMaker connectionMaker = new DConnectionMaker();
    UserDao userDao = new UserDao(connectionMaker);
    
    return userDao;
  }
}

 

 

UserDaoTest는 UserDao가 어떻게 만들어지는지, 어떻게 초기화되어 있는지에 신경 쓰지 않고 팩토리로부터 UserDao 오브젝트를 받아 자신의 원래 역할인 UserDao 테스트를 위해서 활용하기만 하면 된다.

public class UserDaoTest {
  public static void main(String[] args) throws ClassNotFoundException, SQLException {
    UserDao dao = new DaoFactory().userDao();
  }
}

 

설계도로서의 팩토리

이제 각 오브젝트들의 역할과 관계를 분석해보면 UserDao와 ConnectionMaker는 각 애플리케이션의 핵심 데이터 로직과 기술 로직을 담당하고 있고, DaoFactory는 애플리케이션의 오브젝트들을 구성하고 그 관계를 정의하는 책임을 맡고 있다.

다시 말하면 UserDao와 ConnectionMaker는 실질적인 로직을 담당하는 컴포넌트를, DaoFactory는 애플리케이션을 구성하는 컴포넌트의 구조와 관계를 정의한 설계도 같은 역할을 한다고 볼 수 있다. 여기서 설계도는 어떤 오브젝트가 어떤 오브젝트를 사용하는지 정의해 놓은 코드라고 생각하면 된다.

DaoFactory를 분리함으로써 우리는 애플리케이션의 컴포넌트 역할을 하는 오브젝트와 애플리케이션의 구조를 결정하는 오브젝트를 분리할 수 있게 되었다.

 

 

 

제어의 역전(IoC)

제어의 역전이란 프로그램의 제어 흐름 구조가 뒤바뀌는 것이라고 할 수 있다.

일반적으로 프로그램의 흐름은 프로그램 시작 시점에 다음 사용할 오브젝트를 결정하고, 생성하고, 메소드를 호출하고의 반복이다.

제어의 역전에서는 오브젝트가 자신이 사용할 오브젝트를 스스로 선택하거나 생성하지 않는다. 또한 자신도 어떻게 만들어지고 어디서 사용되는지 알 수 없다. 모든 제어 권한을 자신이 아닌 다른 대상에게 위임하여 위임받은 제어 권한을 갖는 오브젝트에 의해 결정되고 만들어진다.

프레임워크도 제어의 역전 개념이 적용된 대표적인 기술이다.

 

 

* 프레임워크라이브러리

라이브러리를 사용하는 애플리케이션 코드는 애플리케이션의 흐름을 직접 제어한다. 동작하는 중에 필요한 기능이 있을 경우 능동적으로 라이브러리를 사용한다.

반면 프레임워크는 애플리케이션 코드가 프레임워크에 의해 사용된다. 프레임워크 위에 개발한 클래스를 등록해두고 프레임워크가 흐름을 주도하는 중에 개발자가 만든 애플리케이션 코드를 사용하도록 만드는 방식이다. 프레임워크는 분명히 '제어의 역전' 개념이 적용되어 있어야 한다. 애플리케이션 코드는 프레임워크가 짜놓은 틀에서 수동적으로 동작해야 하는 것이다.

 

 

 

 

1.5 스프링의 IoC

빈(Bean)

스프링에서는 스프링이 제어권을 가지고 직접 생성하고 관계를 부여하는 오브젝트를 '빈'이라고 부른다. 자바빈과 유사하게 오브젝트 단위의 애플리케이션 컴포넌트를 말하며 스프링 컨테이너가 생성과 관계설정, 사용 등을 제어해주는 제어의 역전이 적용된 오브젝트를 가리킨다.

여기서 주의할 점은 '스프링이 제어권을 가지고 직접 생성하고 관계를 부여하는 오브젝트' 라는 것이다. @Bean이나 @Component 와 같은 어노테이션이 붙어 있지 않은, new로 생성된 일반적인 자바 객체는 스프링의 '빈'에 해당하지 않는다.

 

 

애플리케이션 컨텍스트 - Application Context

스프링에서는 빈의 생성과 관계설정 같은 제어를 담당하는 IoC 오브젝트를 '빈 팩토리(Bean Factory)'라고 부른다.

보통 '빈 팩토리' 보다는 '애플리케이션 컨텍스트'라는 용어를 더 많이 사용하긴 하는데, 이는 IoC 방식을 따라 만들어진 일종의 빈 팩토리라고 생각하면 된다. '빈 팩토리'는 빈을 생성하고 관계를 설정하는 IoC의 기본 기능에 초점을 맞춘 것이고 애플리케이션 컨텍스트는 애플리케이션 전반에 걸쳐 모든 구성 요소의 제어 작업을 담당하는 IoC 엔진이라는 의미가 좀 더 부각된다고 보면 된다.

좀 더 자세한 내용은 이전 포스트에 정리해 두었다.

 

애플리케이션 컨텍스트는 별도의 정보를 참고해서 빈의 생성, 관계 설정 등의 제어 작업을 총괄한다. 애플리케이션 컨텍스트가 직접 정보를 담고 있지는 않지만 별도의 설정 정보를 가져와 활용하는 IoC엔진이라고 볼 수 있다. 이러한 설정정보를 만드는 방법은 여러 가지가 있는데 그 중 하나가 @Configuration 어노테이션이 등록된 클래스이다.

앞선 예제의 DaoFactory를 @Configuration 어노테이션을 추가하여 본격적인 설정정보로 수정해보겠다. 자바 코드로 되어 있지만 XML과 같은 스프링 전용 설정정보라고 생각하면 된다.

@Configuration	// 애플리케이션 컨텍스트 또는 빈 팩토리가 사용할 설정 정보라는 표시
public class DaoFactory {
  @Bean	// 오브젝트 생성을 담당하는 IoC용 메소드라는 표시
  public UserDao userDao() {
    return new UserDao(connectionMaker());
  }
  @Bean
  public ConnectionMaker connectionMaker() {
    return new DConnectionMaker();
  }
}

 

 

...

 

 

 

 

 

 

 

 

 

 

728x90

댓글