티스토리 뷰
Spring으로 개발하면서 개인적으로 궁금했던 내용이다. (나는 Field Injection을 자주 쓴다.)
왜 Field Injection을 쓰면 IntelliJ에서 쓰지 말라고 경고할까?
나는 그동안 Field Injection으로 불편함 없이 개발해왔다. 게다가 Field Injection이 Constructor Injection 보다 작성할 코드가 더 적다. 그러나 IntelliJ는 항상 아래와 같은 Yellow-Block으로 나한테 엄포를 놓는다.
Field Injection을 쓴다는 건 소스코드 상의 Warning과 같다는 건데.. 궁금해져서 찾아볼 겸 이 내용으로 오랜만에 블로그에도 남긴다.
1. Field Injection? Constructor Injection?
먼저 Field Injection과 Constructor 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 Injection을 Field 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
'IT > 개발팁' 카테고리의 다른 글
[Node.js] 미국 가버린 stacktrace를 찾아보자 (0) | 2020.03.21 |
---|---|
[Spring Boot] RestTemplate 활용 1 - 응답 타입 일반화 (0) | 2020.01.19 |
Hibernate에서 동적으로 Eager load Lazy load 하는 법 (0) | 2019.07.08 |
Spring에서 request와 response를 JSON format 으로 한번에 로깅하기 (0) | 2019.03.24 |
[SpringBoot] .properties 파일의 상수를 Enum에 초기화하기 (0) | 2019.01.25 |