Backend/spring

spring bean 주입 방법

dddzr 2023. 5. 10. 12:48

스프링 프레임워크에서 의존성을 주입하는 방법은 3가지가 있습니다.

  • Constructor Injection (생성자 주입) -> 권장
  • Setter Injection (세터 주입)
  • Field Injection (필드 주입)

종류

1.Constructor Injection (생성자 주입)

  • 클래스의 생성자를 통해 의존성을 주입합니다. 클래스에 필요한 의존성을 생성자 매개변수로 선언하고, Spring은 해당 매개변수에 맞는 Bean을 찾아 주입합니다.
  • 주입되는 Bean은 XML 또는 Java Config와 같은 설정 파일에서 정의됩니다.
  • 객체가 생성될 때 한 번만 호출됩니다. 즉, 객체가 처음 만들어질 때 필드 값을 초기화합니다.
public class MyClass {
    private MyDependency myDependency;

    public MyClass(MyDependency myDependency) {
        this.myDependency = myDependency;
    }
}

xml 설정 파일

<bean id="myClass" class="com.example.MyClass">
    <constructor-arg ref="myDependency"/>
</bean>

<bean id="myDependency" class="com.example.MyDependency"/>

 

2. Setter Injection (세터 주입)

  • 클래스의 세터 메서드를 통해 의존성을 주입합니다. 클래스에 필요한 의존성을 세터 메서드로 정의하고, Spring은 해당 메서드를 호출하여 의존성을 주입합니다.
  • 객체가 생성된 후 언제든지 호출될 수 있습니다. 이미 생성된 객체의 필드 값을 수정하거나 변경하는 데 사용됩니다.
public class MyClass {
    private MyDependency myDependency;

    public void setMyDependency(MyDependency myDependency) {
        this.myDependency = myDependency;
    }
}

xml 설정 파일

<bean id="myClass" class="com.example.MyClass">
    <property name="myDependency" ref="myDependency"/>
</bean>

<bean id="myDependency" class="com.example.MyDependency"/>

 

3.Field Injection (필드 주입)

  • 클래스의 필드에 바로 의존성을 주입합니다. 필드에 @Autowired 어노테이션을 사용하면 Spring은 해당 필드에 맞는 Bean을 자동으로 주입합니다.
public class MyClass {
    @Autowired
    private MyDependency myDependency;
}

 

장단점

1. Constructor Injection (생성자 주입)

장점
의존성 주입이 필수적인 경우, 객체를 생성하는 동시에 필요한 의존성을 명확하게 전달할 수 있습니다.
필수적인 의존성을 강제하기 때문에 객체의 일관성과 불변성을 보장할 수 있습니다.
단점
의존성이 많은 경우 생성자의 매개변수가 복잡해질 수 있습니다.
클래스의 변동이 생길 때마다 생성자를 수정해야 할 수 있습니다.


2. Setter Injection (세터 주입)

장점
선택적인 의존성 주입이 가능합니다.
객체 생성 후에도 의존성을 변경할 수 있습니다.
단점
객체 생성 후 세터 메서드를 통해 의존성을 주입하기 때문에, 객체가 완전히 생성되기 전에 사용될 수 있습니다.
세터 메서드를 통해 의존성을 주입하지 않은 경우 NullPointerException 등의 예외가 발생할 수 있습니다.


3. Field Injection (필드 주입)

장점
코드가 간결해지고, 작성하기 쉽습니다.
의존성 주입을 명시적으로 하지 않아도 되므로, 개발자가 코드 작성에 대해 신경 쓸 필요가 없습니다.
단점
테스트하기 어렵습니다. 필드 주입은 명시적인 의존성 주입을 요구하지 않기 때문에, 테스트 환경에서 해당 의존성을 주입하기 어렵습니다.
객체의 일관성과 불변성을 보장하기 어렵습니다.
필드에 직접 접근하기 때문에 캡슐화를 위반할 수 있습니다.

순환참조가 발생 할 수 있습니다. (컴파일 타임 시 에러가 잡히지 않다가 로직이 실행되는 런타임 시에 에러가 잡힘.)

 

 

결론

아래와 같은 이유 때문에 생성자 주입 방식을 권장합니다!!

  • 불변
    생성자 주입은 객체를 생성할 시 딱 한번만 호출되므로, 이후 의존관계를 변경할 일이 없으며 변경의 여지를 만들지 않음.
  • final 키워드 사용 가능
    의존성 주입이 필요한 필드를 final 로 선언가능. 그래서, 혹시라도 값이 설정되지 않는 경우 즉각적으로 컴파일 오류를 뱉어냄.
  • (스프링에서) 순환참조 감지가능 -> 순환참조시 앱구동 실패
  • 테스트 코드 작성 용이