티스토리 뷰

저는 원래는 Field에 바로 붙여서 사용하는것을 좋아하는 사람입니다.

왜냐면 제가 개발하는 분야라고 해봐야 커다란 부분도 아니고 복잡도가 심각하지 않아서 이렇게 해도 큰 문제가 없기 때문이죠.

 

이번 기회에 IntelliJ에 warning도 발생하고 그래서 찾아보았더니 몇가지 이유가 있군요

 

기본적으로 @Autowired를 사용하는 범위는 Field, Setter, Constructor이 있습니다.

 

1. Field

public class Example {

	@Autowired
	private WalkService walkService;

	@Autowired
	private RunService runService;
}

2. Setter

public class Example {

	private WalkService walkService;

	private RunService runService;
    
	@Autowired
	public void setWalkService(WalkService service) {
		walkService = service;
	}
    
	@Autowired
	public void setRunService(RunService service) {
		runService = service;
	}
}

3. Constructor

public class Example {

	private final WalkService walkService;

	private final RunService runService;
    
	@Autowired
	public Example(WalkService walkService, RunService runService) {
		this.walkService = walkService;
		this.runService = runService;
	}
}

 

그냥 봐도 Field에 바로 매핑하는게 아름답지 않나요? 간결해지고...

그렇지만 이렇게 하지 않는게 좋다고 합니다.

 

이유

  1. 너무 많은것을 Injection하게 되면 하나의 클래스가 너무 많은 책임을 가져야 하는데 한두번의 경우에는 상관없지만 복잡한 구조에서는 당연히 문제가 됩니다. 만약에 이것을 생성자에서 받아서 처리한다면 파라메터의 갯수가 많아짐에 따라서 리팩토링을 하여야 하는다는 징조로 받아들이고 처리할수 있다고 합니다. 그러면 Kotlin으로 한다면? 그건 Java가 아니니 다음 이야기로...
  2. 스프링 즉 DI 프레임워크들의 핵심 아이디어는 관리되는 클래스가 DI 컨테이너에 의존성이 없어야 한다고 합니다. 필요한 의존성을 전달하면 독립적으로 인스턴스화 할 수 있는 단순 POJO여야 한다고 하네요. DI 컨테이너 없이도 유닛테스트에서 인스턴스화 하여서 각각으로 테스트가 가능하게 할 수 있는 이점을 가질 수 있습니다. Field Injection이면 private라서 가능하지 않습니다.
  3. final을 이용할 수 있어서 객체가 변하지 않습니다.
  4. Constructor Injection에서 순환 의존성을 가질 경우 BeanCurrentlyCreationException을 발생시켜 주므로 순환 의존성을 알 수가 있다.

그럼 Setter Injection은? 이것도 약간의 문제는 있습니다.

왜냐면 선택적인 주입이므로 상황에 따라서 주입이 가능하죠.

그렇지만 때에 따라서 사용하면 좋을것 같고 객체의 불변성은 막을수가 없을거 같네요.

Spring 3.x Document에서는 Setter Injection을 추천했다고 하네요.

그렇다면 저는 lombok을 이용하여서 @Setter를 붙이고 그냥 사용하고 싶습니다? ㅎㅎ 이건 앞뒤가 안 맞는거 같은... ㅎㅎ

 

더 귀찬긴 하지만 일단 위의 내용대로 본다면 주입하는것은 서로의 장단점이 있겠지만 생성자를 이용하는 방법이 더 좋은것 같긴합니다.

일단 Spring 4.3 부터는 클래스를 완벽하게 프레임워크로부터 분리할 수 있고, 단일 생성자의 경우에는 @Autowired를 붙이지 않아도 자동 주입이 되게 되었다고 합니다. 뭐... 이런 이유로 Spring 4.x Document에서는 Constructor Injection을 권장한다고 하네요.

 

예전에 주니어일때 그냥 찍어내듯이 만들던 Spring이... 이런 묘미가 있군요.

그때는 저런 Warning 안 발생했는데 ㅎㅎ

 

많은 사람들의 의견이 Constructor Injection 사용을 권장하고 있다고 생각합니다.

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/05   »
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
글 보관함