TIL #21 IoC, DI

HYEON JIN CHOI·2024년 5월 21일

Java Spring 프레임워크는 현대 자바 애플리케이션 개발에 있어서 매우 중요한 역할을 한다. Spring 의 핵심 기능 중 하나는 IoC(Inversion of Control)DI(Dependency Injection) 이다. 이 두 개념은 애플리케이션의 구성 요소를 관리하고, 의존성을 효율적으로 처리하는 데 중요한 역할을 한다. 이번 글에서는 IoCDI 의 개념을 이해하고, Spring 에서 이들이 어떻게 적용되는지에 대해 알아보려고 한다.

1. IoC (Inversion of Control)

IoC 는 제어의 역전이라는 개념으로, 전통적인 프로그래밍 방식과는 반대되는 접근 방식을 의미한다. 전통적인 프로그래밍에서는 객체가 직접 자신의 의존성을 생성하고 관리한다. 하지만 IoC 에서는 이러한 제어권이 객체에서 프레임워크로 넘어간다. 즉, 객체의 생성과 관리, 생명 주기를 프레임워크가 담당하게 되는 것이다.

IoC 의 주요 장점은 다음과 같다:

  • 유연성 : 애플리케이션 구성 요소 간의 결합도를 낮춰 유연성을 높인다.
  • 재사용성 : 구성 요소들이 독립적으로 동작할 수 있어 재사용 가능성이 높아진다.
  • 테스트 용이성 : 의존성 주입을 통해 모의 객체(Mock Object)를 쉽게 주입할 수 있어 단위 테스트가 용이하다.

IoC 는 다양한 방식으로 구현될 수 있지만, Spring 에서는 주로 DI 를 통해 구현된다.

2. DI (Dependency Injection)

DI 는 의존성 주입이라는 개념으로, 객체가 자신의 의존성을 직접 생성하는 대신 외부에서 주입받는 방식을 의미한다. DIIoC 의 한 형태로, 애플리케이션의 유연성과 확장성을 높이는 데 기여한다.

DI 의 유형에는 세 가지가 있다.

  • 생성자 주입 : 객체 생성 시점에 필요한 의존성을 생성자를 통해 주입받는 방식이다.
  • 세터 주입 : 생성된 객체에 세터 메서드를 통해 의존성을 주입하는 방식이다.
  • 인터페이스 주입 : 인터페이스를 통해 의존성을 주입하는 방식으로, 일반적으로 잘 사용되지 않는다.

DI 를 사용하면 다음과 같은 이점이 있다.

  • 결합도 감소 : 구성 요소 간의 결합도를 낮춰 유지보수성을 높인다.
  • 테스트 용이성 : 의존성 주입을 통해 쉽게 모의 객체를 주입할 수 있어 테스트가 용이하다.
  • 구성 관리 용이 : 애플리케이션의 구성 요소들을 중앙에서 관리할 수 있어 변경 사항에 대한 대응이 쉽다.

3. Spring에서의 IoC와 DI

Spring 프레임워크는 IoC 컨테이너를 통해 IoCDI 를 구현한다. Spring IoC 컨테이너 는 객체의 생성, 구성, 생명 주기를 관리하며, 이를 통해 애플리케이션의 구성 요소들이 독립적으로 동작할 수 있도록 한다.

Spring IoC 컨테이너 의 주요 구성 요소는 다음과 같다:

  • Bean : Spring IoC 컨테이너가 관리하는 객체를 의미한다. Bean은 XML 설정 파일이나 자바 어노테이션을 통해 정의된다.
  • BeanFactory : 가장 기본적인 IoC 컨테이너로, Bean의 생성과 관리를 담당한다.
  • ApplicationContext : BeanFactory를 확장한 IoC 컨테이너로, 보다 많은 기능을 제공하며 일반적으로 더 많이 사용된다.

Spring 에서 DI 는 주로 어노테이션을 통해 구현된다. 대표적인 어노테이션으로는 다음이 있다.

  • @Autowired : 자동으로 의존성을 주입하는 어노테이션이다.
  • @Qualifier : 특정 빈을 선택하여 주입할 때 사용되는 어노테이션이다.
  • @Resource : JSR-250 표준 어노테이션으로, 이름을 기반으로 의존성을 주입한다.

다음은 간단한 예제 코드이다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class MyService {
    private final MyRepository myRepository;

    @Autowired
    public MyService(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    public void doSomething() {
        myRepository.save();
    }
}

위 예제에서 MyService 클래스는 MyRepository 객체를 생성자 주입을 통해 주입받는다. 이를 통해 MyService 클래스는 MyRepository 에 대한 의존성을 외부에서 주입받게 되며, 이는 DI의 대표적인 예이다.

4. 회고

IoC와 DI는 Java Spring 프레임워크의 핵심 개념으로 애플리케이션의 유연성과 확장성을 크게 향상시키기 때문에, Spring의 IoC 컨테이너와 다양한 DI 기법을 이해하고 활용하면 더 효율적이고 유연한 애플리케이션을 개발할 수 있을 것이라 생각한다.

0개의 댓글