개발 공부중

[Spring] 의존성 주입(DI) 방식 비교와 빈(Bean) 충돌 해결하기 본문

SPRING BOOT

[Spring] 의존성 주입(DI) 방식 비교와 빈(Bean) 충돌 해결하기

개발자 leelee 2026. 1. 25. 22:33

생성자 주입 (Constructor Injection)

 

객체가 생성되는 시점에 딱 한 번만 호출되어 부품을 끼우는 방식

코드의 안전성과 불변성을 보장한다.

@Component
public class Car {
    private final Engine engine; // final을 붙이기

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

 

수정자 주입 (Setter Injection)

 

 

객체를 먼저 만들어 놓고, 나중에 set~ 메서드를 통해 부품을 끼우는 방식입니다.
NullPointerException 에러가 발생 가능성 높

@Component
public class Car {
    private Engine engine; // 나중에 바꿀 수 있어서 final을 못 씀

    @Autowired
    public void setEngine(Engine engine) {
        this.engine = engine;
    }
}

 

 

Lombok 

 

생성자 주입이 좋지만 코드가 길어지는 단점이 있어서,

Lombok(롬복) 라이브러리를 써서 간단하게 할 수 있다. 

@Component
@RequiredArgsConstructor // final이 붙은 애들만 모아서 생성자를 자동으로 만들어줌
public class Car {
    private final Engine engine; // 생성자 직접 안 써도 됨
}

 

 

여러개의 빈이 선택될 수 있을  해결방법 (빈 충돌 해결)

만약 Engine 인터페이스를 상속받은 GasolineEngine과 ElectricEngine이 둘 다 스프링 빈으로 등록되어 있다면, 

스프링은 어떤 것을 주입해야 할지 몰라서 오류가 난다. 

 

 

1. @Primary 

메인 부품이 정해져 있을 때 우선순위 지정

@Component
@Primary  // 똑같은 엔진이 여러 개면 기본선택은 이거
public class ElectricEngine implements Engine { ... }

@Component
public class GasolineEngine implements Engine { ... }

 

 

2. @Qualifier 

여러 부품을 골고루 섞어 써야 할 때 등 때에 따라서 지정

@Component
@Qualifier("fastEngine") // 이 부품의 별명을 'fastEngine'으로 정함
public class GasolineEngine implements Engine { ... }

// 주입받는 곳
@Component
public class Car {
    private final Engine engine;

    public Car(@Qualifier("fastEngine") Engine engine) { // 별명이 'fastEngine'인 애를 가져옴
        this.engine = engine;
    }
}

 

 

3. 필드 이름 매칭 

스프링은 똑같은 타입이 여러 개 있으면, 마지막 수단으로 변수(필드) 이름과 똑같은 이름의 빈이 있는지 찾음

@Component
public class GasolineEngine implements Engine { ... }

@Component
public class ElectricEngine implements Engine { ... }

@Component
public class Car {
    // 변수 이름을 'electricEngine'으로 지으면, 스프링이 알아서 ElectricEngine을 가져옴
    @Autowired
    private Engine electricEngine; 
}

 

세 가지 중, 공통적으로 많이 쓰는 것에 @Primary를 붙이고,

특별한 경우에만 @Qualifier로 지목해서 쓰는 방식을 사용하기

Comments