왜 Spring에서는 필드 주입을 지양하나?

반응형

Spring Framework에서 의존성 주입이란 객체지향 프로그래밍에서 중요한 원칙 중 하나인 의존성 역전 원칙(Dependency Inversion Principle)을 적용하는 방법입니다. 이를 통해 객체 간의 결합도를 낮추고 코드의 유연성을 높일 수 있습니다.

이전 글에서 의존성 주입에 대한 간단한 설명을 작성했는데요. 이번에 의존성 주입 방법에 대해서 알아보겠습니다.

 

Spring에서 의존성 주입을 하는 방법은 크게 세 가지입니다.

  1. 생성자 주입(Constructor Injection)
  2. Setter 주입(Setter Injection)
  3. 필드 주입(Field Injection)

이번 글에서는 이 세 가지 방법에 대해 자세히 알아보고 왜 필드 주입을 권장하지 않는지에 대해 살펴보겠습니다.

 

1. 생성자 주입(Constructor Injection)

생성자 주입은 의존성을 주입받는 클래스의 생성자를 통해 의존성을 주입하는 방법입니다. 이 방법은 객체가 생성될 때 의존성을 한번에 주입받기 때문에 의존성 주입 후에 변경이 불가능하다는 점에서 불변성을 확보할 수 있다는 장점이 있습니다.

@Service
public class ExampleService {

    private final ExampleRepository exampleRepository;

    public ExampleService(ExampleRepository exampleRepository) {
        this.exampleRepository = exampleRepository;
    }
}

 

2. Setter 주입(Setter Injection)

Setter 주입은 의존성을 주입받는 클래스의 setter 메서드를 통해 의존성을 주입하는 방법입니다. 이 방법은 객체가 생성된 후에도 의존성을 변경할 수 있다는 점에서 유연성을 제공하지만, 의존성이 변경될 가능성이 있기 때문에 불변성을 확보하기 어렵습니다.

@Service
public class ExampleService {

    private ExampleRepository exampleRepository;

    @Autowired
    public void setExampleRepository(ExampleRepository exampleRepository) {
        this.exampleRepository = exampleRepository;
    }
}

 

 

3. 필드 주입(Field Injection)

필드 주입은 의존성을 주입받는 클래스의 필드에 직접 의존성을 주입하는 방법입니다. 이 방법은 코드가 간결하다는 장점이 있지만, 의존성이 변경될 가능성이 있고 테스트하기 어렵다는 단점이 있습니다.

@Service
public class ExampleService {

    @Autowired
    private ExampleRepository exampleRepository;
}

 Spring에서는 필드가 private으로 선언되어 있음에도 불구하고 필드 주입이 가능한데, 이게 어떻게 가능할까요?

바로 Java의 Reflection API를 사용하면 접근 제한자를 무시하고 필드에 직접 접근할 수 있습니다. Spring Framework는 이러한 Reflection API를 사용해 private으로 선언된 필드에도 의존성을 주입할 수 있습니다.

 

그런데 필드 주입을 권장하지 않습니다.

Spring에서 필드 주입을 권장하지 않는 주된 이유는 다음과 같습니다. 

필드 주입을 사용하면 의존성 주입을 위해 Spring Container가 필요하게 되므로 테스트가 어렵습니다. 객체를 직접 생성하면서 의존성을 주입하는 생성자 주입을 사용하면, 테스트가 더 용이하게 됩니다.

필드 주입을 사용하면 객체가 생성된 후에도 의존성이 변경될 수 있습니다. 이는 불변성을 해칠 수 있으므로 객체의 안정성을 보장하기 어렵습니다. 생성자 주입을 사용하면, 객체가 생성될 때 의존성을 한번에 주입받아 불변성을 확보할 수 있습니다.

필드 주입을 사용하면 순환 참조 문제가 발생할 가능성이 있습니다. 순환 의존성은 어플리케이션의 복잡성을 증가시키고 버그를 유발할 수 있습니다. 이러한 문제를 방지하기 위해서는 생성자 주입을 사용하는 것이 좋습니다. 

 

따라서, Spring에서는 생성자 주입을 가장 권장하는 방식으로 간주하며 필드 주입을 지양하고 있습니다. 이를 통해 테스트 용이성, 불변성, 순환 참조 문제 등을 효과적으로 해결할 수 있습니다.