[Spring Boot] IoC 와 DI
IoC
스프링 프레임워크의 기본 개념 중 하나로, 프레임워크가 애플리케이션의 종속성을 관리하고 제어할 수 있게 합니다. IoC는 객체를 생성하고 그 종속성을 관리하는 제어를 애플리케이션 코드에서 스프링 컨테이너로 전환하는 것을 의미합니다.
간단한 예제를 통해 Spring Boot의 IoC를 설명해 보겠습니다:
Car 클래스가 Engine 클래스에 종속되는 상황을 가정해 보겠습니다. Spring Boot의 IoC 없이는 Car 클래스 내에서 Engine의 인스턴스를 직접 생성할 수 있습니다.
public class Car {
private Engine engine;
public Car() {
this.engine = new Engine(); // Engine 인스턴스를 직접 생성
}
// Car의 다른 메서드
}
public class Engine {
// Engine 클래스 구현
}
위 예제에서 Car 클래스는 Engine의 인스턴스를 생성하는 책임을 갖고 있습니다. 이는 Car와 Engine 간의 강한 결합을 생성하여 코드를 유지 및 테스트하기 어렵게 만듭니다.
이제 Spring Boot의 IoC가 이 예제에 어떻게 적용될 수 있는지 살펴보겠습니다:
public class Car {
private Engine engine;
public Car(Engine engine) {
this.engine = engine; // Car 클래스가 Engine 인스턴스에 종속됨
}
// Car의 다른 메서드
}
public class Engine {
// Engine 클래스 구현
}
이 수정된 예제에서 Car 클래스는 더 이상 Engine의 인스턴스를 직접 생성하지 않습니다. 대신 생성자를 통해 Engine의 인스턴스를 받습니다. 이를 생성자 주입이라고 합니다.
이제 Spring Boot의 IoC 컨테이너가 어떻게 종속성을 관리해 주는지 살펴보겠습니다:
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class MyApp {
@Bean
public Engine engine() {
return new Engine(); // Engine의 인스턴스 생성
}
@Bean
public Car car() {
return new Car(engine()); // Engine 인스턴스를 Car에 주입
}
public static void main(String[] args) {
SpringApplication.run(MyApp.class, args);
}
}
이 Spring Boot 예제에서는 주요 애플리케이션 클래스 MyApp을 정의했습니다. @SpringBootApplication으로 주석이 달린 이 클래스는 Spring Boot의 자동 구성을 트리거합니다.
또한 두 개의 @Bean 메서드를 정의했습니다:
◇ engine(): 이 메서드는 Engine의 인스턴스를 생성합니다.
◇ car(): 이 메서드는 Car의 인스턴스를 생성하고 engine() 메서드로 생성된 Engine 인스턴스를 주입합니다.
애플리케이션이 시작되면 Spring Boot의 IoC 컨테이너가 Car와 Engine 클래스의 인스턴스를 생성하고 관리합니다. 필요한 종속성(이 경우 Engine 인스턴스)을 의존 클래스(이 경우 Car 클래스)에 주입합니다. Spring Boot의 IoC 컨테이너가 제공하는 이 제어의 역전은 결합을 느슨하게 하고 코드를 모듈화 하며 유지 보수 및 테스트가 용이하도록 만듭니다.
DI
DI(Dependency Injection, 의존성 주입)는 객체 간의 의존 관계를 외부에서 주입하는 방법을 말합니다. 이것은 객체가 직접 의존하는 객체를 생성하는 것이 아니라 외부에서 받아서 사용하는 것을 의미합니다. 그리고 제어의 역전(IoC)을 구현하기 위한 방법이 DI입니다.
public class Car {
@Autowired
private Engine engine;
// Car 클래스의 다른 메서드들
}
public class Engine {
// Engine 클래스의 구현
}
@Autowired를 사용함으로써 스프링 컨테이너가 Engine의 객체를 생성해서 Car에게 넘겨준 것과 같은 의미입니다.
덧붙여 @Component 란
@Component 어노테이션은 Spring 프레임워크에서 빈(Bean)으로 등록할 클래스를 표시하는 데 사용됩니다. 이 어노테이션을 사용하면 Spring IoC 컨테이너가 해당 클래스를 자동으로 검색하고 빈으로 등록합니다.
간단한 예제를 통해 @Component를 설명해 보겠습니다.
예를 들어, 자동차(Car) 클래스를 Spring IoC 컨테이너에서 빈으로 등록하고 싶다고 가정해 봅시다.
import org.springframework.stereotype.Component;
@Component
public class Car {
// Car 클래스의 구현
}
위의 코드에서 @Component 어노테이션은 Car 클래스를 Spring의 컴포넌트 스캔(Component Scan) 대상으로 지정합니다. 이제 Spring IoC 컨테이너가 실행될 때 Car 클래스를 검색하고, 빈으로 등록합니다.