티스토리 뷰

반응형

 Spring으로 개발하면서 개인적으로 궁금했던 내용이다. (나는 Field Injection을 자주 쓴다.)



왜 Field Injection을 쓰면 IntelliJ에서 쓰지 말라고 경고할까?



 나는 그동안 Field Injection으로 불편함 없이 개발해왔다. 게다가 Field InjectionConstructor Injection 보다 작성할 코드가 더 적다. 그러나 IntelliJ는 항상 아래와 같은 Yellow-Block으로 나한테 엄포를 놓는다.





 Field Injection을 쓴다는 건 소스코드 상의 Warning과 같다는 건데.. 궁금해져서 찾아볼 겸 이 내용으로 오랜만에 블로그에도 남긴다.



1. Field Injection? Constructor Injection?

 먼저 Field InjectionConstructor Injection은 Spring에서 DI(Dependency Injection)을 구현하는 방법 중 하나이다. 예제만으로 간단하게 설명할 수 있을 듯하다. 아래 예제로 설명을 대체한다.


Field Injection 예제

@Service
public class StudentService {

    @Autowired
    private StudentRepository studentRepository;

    public List<Student> getStudentListAll() {
        return studentRepository.findAll();
    }
}



Constructor Injection 예제

@Service
public class StudentService {

    private StudentRepository studentRepository;

    @Autowired
    StudentService(StudentRepository studentRepository) {
        this.studentRepository = studentRepository;
    }

    public List<Student> getStudentListAll() {
        return studentRepository.findAll();
    }
}



2. 왜 Constructor Injection인가? 그리고 반박.

 구글링을 조금 해보면 왜 Constructor InjectionField Injection보다 권장하는지에 대해 잘 나와있다. 나는 Field Injection이 더 간단하고 깔끔하다고 생각해서 Field Injection을 종종 사용하는 개발자니까 반박할 수 있는 것은 조목조목 반박해보겠다.


Field Injection으로는 Immutable Object를 만들 수 없다.

 → 맞는 말임. 누가 Bean Object의 의존성을 Runtime에 변경하겠냐만.. 실수 방지 차원에서 좋다고 생각한다. Constructor Injection은 final 키워드를 활용해서 Immutable Object를 만들 수 있다.


Field Injection을 쓰면 의존성 외부에서 한눈에 확인하기 어렵다.

 → 어차피 의존성 많아지면 Contructor Injection도 한눈에 확인하기 어렵기는 마찬가지라고 생각한다. 게다가 IDE의 기능을 쓰면 Field Injection의 경우에도 의존성을 한눈에 확인할 수 있다.



Field Injection을 쓰면 unitTest 할 때 의존성을 바꾸는 것이 어렵다.

 → 나는 의존성 주입 시 전략패턴을 활용한다. 그러니까 @Autowired로 주입할때 항상 인터페이스를 작성한다. 그리고 unitTest할 때 테스트시 2개 작성하면 된다.


 unitTest시 의존성을 바꾸는 것이 어려우면 테스트 파일을 2개 작성하면 된다. 의존성을 바꿔가며 테스트 하는 것이 불가능 한 것인양 설명하는 것이 아쉽다. 오히려 의존성을 바꿔가며 수행하는 테스트를 하나의 파일에서 작성하는 것 자체가 오히려 혼돈을 줄 수 있다고 생각한다.


Field Injection은 간단해서 의존이 많이 생기는 것에 경각심을 갖기 어렵다.

 → 경각심을 가지면 된다. 경각심을 갖기 위해 Construction Injection 선언의 귀찮음을 감수하긴 싫다. 이건 개발자 개인의 의지 문제이지 Field Injection의 구조적 문제가 아니다.


Constructor Injection을 쓰 new 키워드로 테스트할 수 있다.

 → 맞는 말.. 테스트 방법이 다양해지는 것은 좋다. 다만 위에서 언급했듯 나는 @Mock, @Spy 등을 활용해 mocking과 실제 bean object 주입을 자유롭게 하고 있다. 이 설정이 바뀌어야할 때는 테스트 파일을 하나 더 만든다. 파일이 아예 분리되면 테스트 코드들이 잘 정리되는 효과가 있다고 생각한다.


어떤 문제가 생겨 DI에 실패했을 때 Constructor Injection은 생성자에서 처리할 수 있다.

 → 맞는 말임. Field Injection은 이 경우 NullPointerException을 막기 어렵다. 하지만 이 문제는 주로 개발 과정에 일어난다. 그치만 맞는 말은 맞는 말이니까.. 인정.




나도 Constructor Injection의 장점에 대해 알아볼 겸 포스트를 작성했는데 앞으로 Constructor Injection을 자주 써야겠다는 생각이 들었다. 이 포스트를 보신 고수님들의 Field Injection과 Constructor Injection에 대한 좋은 의견을 기다린다.




출처 및 참고

https://stackoverflow.com/questions/39890849/what-exactly-is-field-injection-and-how-to-avoid-it

https://nesoy.github.io/articles/2018-12/Spring-Field-Injection

https://docs.spring.io/spring/docs/4.2.x/spring-framework-reference/html/beans.html#beans-constructor-injection







«   2021/12   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
글 보관함
Total
759,125
Today
15
Yesterday
253