본문 바로가기
IT개발/Spring Framework

Spring IoC(Inversion of Control) - 제어의 역행(스프링/프레임워크/백엔드/개발/프로그래밍)

by 시간기억자 2024. 12. 4.
반응형

Spring IoC(Inversion of Control)는 객체의 생성 및 관리 방식을 바꾸는 개념으로, 객체 간의 의존성을 효과적으로 관리하는 데 도움을 주는 Spring Framework의 핵심 원리입니다.

 

1. 전통적인 방식

 

전통적인 객체 생성 방식에서는 객체가 자신이 필요한 다른 객체를 직접 생성합니다. 예를 들어, 자동차를 만들기 위한 코드가 다음과 같다고 가정해 보겠습니다.

public class Engine {
    public void start() {
        System.out.println("Engine started.");
    }
}

public class Car {
    private Engine engine;

    public Car() {
        this.engine = new Engine(); // Car가 직접 Engine을 생성
    }

    public void drive() {
        engine.start();
        System.out.println("Car is driving.");
    }
}

 

위 코드에서 Car 클래스는 Engine 클래스를 직접 생성합니다. 이렇게 되면 Car 클래스와 Engine 클래스는 강하게 결합되어 있습니다. 만약 Engine 클래스를 바꾸고 싶다면 Car 클래스도 수정해야 합니다. 이처럼 의존성이 강하게 결합되어 있으면 유지보수가 어렵고 코드 변경이 번거로워집니다.

 

2. IoC의 개념

**IoC(Inversion of Control)**는 "제어의 역전"이라는 의미로, 객체의 생성과 의존성 관리의 책임을 객체 자신이 아닌 외부로 넘기는 것을 말합니다. 즉, 객체가 필요한 의존성을 스스로 생성하는 것이 아니라, 외부에서 주입받는 방식입니다.

 

3. IoC의 장점

 

IoC를 사용하면 다음과 같은 장점이 있습니다:

 

  • 유연성: 객체 간의 결합도가 낮아져서 코드 변경이 용이해집니다. 새로운 객체를 쉽게 교체할 수 있습니다.
  • 테스트 용이성: 테스트할 때 실제 객체 대신 mock 객체를 주입할 수 있어 단위 테스트가 쉬워집니다.
  • 유지보수성: 코드가 더 깔끔해지고, 공통 관심사(로깅, 보안 등)를 별도로 관리할 수 있습니다.

4. Spring IoC 컨테이너

Spring Framework에서는 IoC를 구현하기 위해 IoC 컨테이너를 사용합니다. IoC 컨테이너는 객체를 생성하고, 이 객체 간의 관계를 관리하는 역할을 합니다. Spring IoC 컨테이너의 두 가지 주요 유형은 다음과 같습니다:

 

  • BeanFactory: 가장 기본적인 IoC 컨테이너로, 객체를 생성하고 관리합니다.
  • ApplicationContext: BeanFactory를 확장한 것으로, 더 많은 기능을 제공하며, 메시지 리소스, 이벤트 처리 등 다양한 기능을 지원합니다.

 

5. Spring에서 IoC 사용 예

아래는 Spring IoC를 사용하는 간단한 예제입니다.

 

5.1. 의존성 주입을 통한 IoC 구현

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.stereotype.Component;

// Engine 클래스
@Component
public class Engine {
    public void start() {
        System.out.println("Engine started.");
    }
}

// Car 클래스
@Component
public class Car {
    private final Engine engine;

    // 생성자를 통해 Engine 객체를 주입받음
    public Car(Engine engine) {
        this.engine = engine;
    }

    public void drive() {
        engine.start();
        System.out.println("Car is driving.");
    }
}

// Main 클래스
public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(Main.class);
        Car car = context.getBean(Car.class); // Car 객체를 IoC 컨테이너에서 가져옴
        car.drive();
    }
}

 

위 코드에서 Car 클래스는 이제 Engine 객체를 직접 생성하지 않고, 외부에서 주입받습니다. ApplicationContext를 통해 Car 객체를 요청하면, Spring이 필요한 Engine 객체를 자동으로 주입해 줍니다.

결론

 

Spring IoC는 객체 생성과 관리의 책임을 외부로 넘겨줌으로써, 코드의 유연성과 유지보수성을 높여주는 중요한 개념입니다. IoC 컨테이너를 통해 객체 간의 의존성을 관리하면, 애플리케이션을 더 쉽게 개발하고 테스트할 수 있습니다.

 


 

  • IoC(Inversion Of Control) : 제어의 역행
  • IoC의 개념을 적용함으로 인해 얻을 수 있는 장점 : Container 기능을 제공하여 객체간의 결합도를 떨어뜨릴 수 있다.

위의 경우 클래스 하나가 바뀌니 그 클래스와 관계있는 다른 클래스도 모두 바꾸어줘야 한다.
이는 결합도가 높다는 것이고 결합도가 높으면 유지보수가 힘들어진다.

 

 

  • IoC 개념
    : 개발자가 new 연산자로 객체를 직접 만드는게 아니라, Container에게 객체를 대신 만들어달라고 해서 객체간의 결합도를 떨어뜨리는 개념이라고 생각하면 된다.
  • Spring의 가장 기본적인 기능은 Container 기능이라 할 수 있다.
  • 객체를 누군가가 대신 생성해준다면 생성 결합을 줄여줌으로써 결합도를 낮출 수 있다.
  • 결합도를 낮추기 위해서는
    → 인터페이스 사용 ( 메소드 오버라이드에 의한 다형성)
    → Factory 클래스 사용(Factory 클래스 만들때도 인터페이스 만들어야 한다 → 메소드 오버라이드에 의한 다형성)

  • 제어의 역행 의미는 다른 누군가가 대신 객체를 만들어주면 그 객체를 제공받아 프로그램을 만드는 개념이다.
  • 원래 프로그래머가 명령을 통해 객체를 생성, 사용, 소멸시키는데
    그걸 컨테이너 기능을 통해 객체를 생성, 사용, 소멸시키는 것이다
  • 그러기 위해서는 Factory 클래스가 필요하다.
  • 컨테이너는 객체 생성이 가능하고, 필요시 관계도 형성시킬 수 있고 소멸도 시킬 수 있다.
    (컨테이너는 팩토리 클래스보다 한단계 상위 단계라고 생각하면 된다.)

 

반응형

댓글