Spring 개념정리

[Spring] 스프링 DI(Dependency Injection)

개발자 문문 2025. 6. 24. 22:38

안녕하세요. 개발자 문문입니다. 

오늘은 스프링 DI, 의존성 주입에 대해 공부하겠습니다.

 

스프링에서 말하는 의존이란 무엇일까요?

아래의 클래스를 예시로 설명 드리겠습니다.

 

public class Engine {
	String type;
    
    public Engine(String type)
    {
    	this.type = type;
    }
    
    public String getType()
    {
    	return type;
    }
}


public class Car {
    private Engine engine;

    public Car() {
        this.engine = new Engine("엔진1");  // 강한 결합 (tight coupling)
    }
    
    public void print() {
    	System.out.println("엔진 종류 : " + engine.getType());
    }
}

 

위처럼 정의되어 있는 Engine, Car 클래스가 있습니다. 여기서 만약 getType() 메소드 명을 getEngineType()으로 변경한다면 Engine 클래스의 메서드를 사용중인 Car의 코드 또한 변경이 필요합니다.

이처럼 의존이란 한 객체가 다른 객체의 기능을 사용할 때 변경에 의한 영향을 받는 관계를 말합니다. 

 

의존성을 주입하는 방법 3가지를 알아보겠습니다.

1. 생성자 기반 수동 주입

2. @Configuration + @Bean

3. 자동 주입

 

 

위 예시 코드를 3가지 방법으로 의존성 주입을 해보겠습니다.

 

1. 생성자 기반 수동 주입(Spring 사용 X)

public class Engine {
    private String type;

    public Engine(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }
}

public class Car {
    private Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }

    public void print() {
        System.out.println("엔진 종류 : " + engine.getType());
    }
}

public class Main {
    public static void main(String[] args) {
        Engine engine = new Engine("엔진1");   // 수동 생성
        Car car = new Car(engine);           // 수동 주입
        car.print();
    }
}

 

 

 

2. @Configuration + @Bean (직접 Bean을 등록하여 주입하기)

 

- 스프링 설정 클래스 (@Configuration)에서 @Bean 등록

@Configuration
public class AppConfig {

    @Bean
    public Engine engine() {
        return new Engine("엔진1");
    }

    @Bean
    public Car car() {
        return new Car(engine());  // 생성자 주입
    }
}
public class Engine {
    private String type;

    public Engine(String type) {
        this.type = type;
    }

    public String getType() {
        return type;
    }
}

public class Car {
    private final Engine engine;

    public Car(Engine engine) {
        this.engine = engine;
    }

    public void print() {
        System.out.println("엔진 종류 : " + engine.getType());
    }
}

 

- @Import로 설정 클래스 등록 후 생성된 빈 객체 불러오기(의존성 주입)

@SpringBootApplication
@Import(AppConfig.class)
public class App {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(App.class, args);
        Car car = context.getBean(Car.class);
        car.print();
    }
}

 

3. 필드를 통한 자동 의존성 주입

@Component
public class Engine {
    private String type;

    public Engine() {
        this.type = "엔진1";
    }

    public String getType() {
        return type;
    }
}

@Component
public class Car {

    @Autowired
    private Engine engine;

    public void print() {
        System.out.println("엔진 종류 : " + engine.getType());
    }
}
@SpringBootApplication
public class App {
    public static void main(String[] args) {
        ApplicationContext context = SpringApplication.run(App.class, args);
        Car car = context.getBean(Car.class);
        car.print();
    }
}

 

- @Autowired : 스프링에서 생성되어 있는 빈 객체 중 @Autowired가 붙어 있는 필드 타입을 찾아서 주입

 

스프링은 자동 주입, 라이프사이클 관리 등 객체 생성, 관리를 위한 기능을 제공하는데 이는 빈으로 등록한 객체에만 적용되기 때문에 빈 생성과 의존성 주입은 반드시 필요합니다.