공간정보아카데미

스프링에서 Bean은 어떻게 등록되고 주입될까? (XML & Annotation 비교)

minjava 2025. 9. 2. 21:34

 

1. 기본 개념

스프링에서 DI(의존성 주입)는 **“필요한 객체를 직접 new 해서 쓰지 않고, 외부에서 넣어준다”**는 거예요.

DI 방식은 크게 3가지가 있어요:

  1. 필드 주입 → @Autowired private EmpDAO dao;
  2. Setter 주입 → setEmpDAO(EmpDAO dao) 같은 setter로 주입
  3. 생성자 주입 → public EmpServiceImpl(EmpDAO dao) { this.dao = dao; }

2. 생성자 주입 방식의 원리

당신이 적으신 코드:

public class EmpServiceImpl implements EmpService {
    private EmpDAO dao;

    public EmpServiceImpl(EmpDAO dao) {
        this.dao = dao;
    }
}

👉 여기서 중요한 건 EmpDAO를 직접 new 하지 않았다는 점이에요.
즉, 누군가 new EmpServiceImpl(dao객체)를 호출할 때 외부에서 EmpDAO를 넣어주도록 강제한 겁니다.


3. 스프링에서 동작할 때

XML 기반이라면:

<bean id="empDAO" class="myspring.EmpDAO"/>
<bean id="empService" class="myspring.EmpServiceImpl">
    <constructor-arg ref="empDAO"/>
</bean>

Annotation 기반이라면:

@Service
public class EmpServiceImpl implements EmpService {
    private final EmpDAO dao;

    @Autowired   // 생략 가능 (Spring 4.3+)
    public EmpServiceImpl(EmpDAO dao) {
        this.dao = dao;
    }
}

👉 원리:

  • 스프링이 컨테이너에서 empDAO Bean을 먼저 생성.
  • empService Bean을 만들 때 생성자를 보고 “EmpDAO 필요하네?” → 컨테이너에 있는 empDAO를 찾아서 넣어줌.

4. 왜 굳이 생성자 주입을 쓰나?

  • 불변성: final로 선언 가능 → 런타임 중 바뀌지 않음.
  • 테스트 용이: new 할 때 원하는 가짜 DAO(Mock 객체) 넣을 수 있음.
  • 순환 참조 문제 방지: 생성자 주입은 의존성이 명확히 드러나서 구조가 깔끔해짐.

✅ 정리

  • EmpServiceImpl(EmpDAO dao) 생성자 방식은 스프링이 Bean을 만들면서 자동으로 EmpDAO를 넣어주는 DI 방법이에요.
  • @Autowired는 “자동으로 찾아 넣어라”라는 지시어지만, 사실 생성자에 파라미터 있으면 스프링이 알아서 matching Bean을 넣어줍니다.
  • 즉, @Autowired 없이도 생성자 하나만 있으면 스프링이 자동으로 주입해줘요. (Spring 4.3 이상)