본문 바로가기
Spring

[Spring] 왜 Constructor Injection(생성자 주입)을 사용해야 할까?

by 노력남자 2019. 11. 6.
반응형

왜 Constructor Injection(생성자 주입)을 사용해야 할까?

 

이전 포스팅에서 Field Injection, Setter Injection 대신 Constructor Injection을 사용해야한다고 했는데 어떤 장점이 있어서 사용해야 하는지 알아보자.

 

1. Constructor Injection(생성자 주입)

 

public class SpellChecker { 
	private TextDictionary textDictionary;
	private VoiceDictionary voiceDictionary;
     
	@Autowired //4.3부터 단일 생성자일 경우 @Autowired 생략가능
	public SpellChecker(TextDictionary t, VoiceDictionary v) {
		this.textDictionary = t;
		this.voiceDictionary = v;
	}     
}

 

2. Setter Injection(세터 주입)

 

public class SpellChecker { 
	private TextDictionary textDictionary;
	private VoiceDictionary voiceDictionary;
     
	@Autowired
	public void setTextDictionary(TextDictionary t) {
		this.textDictionary = t;
	}
    
	@Autowired
	public void setVoiceDictionary(VoiceDictionary v) {
		this.voiceDictionary = v;
	}     
}

 

3. Field Injection(필드 주입)

 

public class SpellChecker { 
	@Autowired
	private TextDictionary textDictionary;
    
	@Autowired
	private VoiceDictionary voiceDictionary;     
}

 

 

Constructor Injection 장점

 

단일 책임의 원칙 위반

 

Constructor Injection 이외에 다른 DI 방법들에 비해 단일 책임을 위반하게 코딩한 것을 느끼게 해준다. 하나의 클래스 안에 Constructor Injection의 파라미터가 많아지면 많아질 수록 다중 책임을 맡고 있다는 걸 알 수 있어 리팩토링 기준점에 좋은 정보가 된다.

 

(개인적인 생각) 개발하면서 Field Inejction을 사용해왔는데 사실 Field나 Setter Injection을 사용해도 DI한 클래스들이 많아지면 단일 책임의 원칙을 위반한 것을 알 수 있다. 이 문제는 개발자의 역량이라 생각된다.

 

테스트 용이성

 

테스트할 때 DI를 할 수 있어 편리하다. Field Injection을 썼을 땐 Dependency를 임의로 바꿀 수 없기 때문에 테스트할 때 불편하다.

 

DI 컨테이너 결합도

 

Spring 4.3부터 단일 생성자일 경우 @Autowired를 생략할 수 있기 때문에 스프링말고 다른 DI 컨테이너를 사용해도 아무 문제가 없다.

 

불변성

 

Contructor Injection엔 final을 붙힐 수 있다. Field Inejction은 붙힐 수 없다.

 

순환 의존성


Constructor Injection에서 순환 의존성을 가질 경우 BeanCurrentlyCreationExeption이 발생되어 문제점을 알 수 있다.

 

 

음.. 그렇다면 Setter Injection은 아예 안쓰는건가?

 

아예 안쓰는건 아니고 Setter Injection은 선택적 의존성들을 주입할 때 사용한다.

 

런타임시 이미 주입된 객체말고 다른 객체가 필요해서 의존성을 바꾸는 경우가 있을 때 사용하면 된다.

 

 

마치며

 

DI를 공부하면서 정말 많은 정보를 얻었습니다. Intellij에서 Field Injection을 사용하면 경고 문구가 나왔는데 이를 무시하고 그냥 사용한 제 자신을 반성하며... 앞으로는 Field Injection을 사용하지 않고 Constructor Injection을 사용해야 겠습니다. 

 

 

참고

 

https://www.vojtechruzicka.com/field-dependency-injection-considered-harmful/

반응형

댓글