[Spring] 스프링 의존성 주입(Dependency Injection)


의존성 주입(Dependency Injection, DI)란 객체들 간의 의존 관계를 외부(컨테이너)에서 생성해주는 것입니다.

DI를 사용하지 않을 경우

kakaogames가 odin을 생성 및 의존

class kakaogames {
	private Odin odin;
	
	public kakaogames() {
		 odin = new Odin();
	}
}

normal

DI를 사용할 경우

kakaogames가 odin에 의존 (생성하지는 않음)

누군가 kakaogames와 odin을 생성하고 의존성을 주입해주었습니다.

class kakaogames {
	private final Odin odin;
	
	public kakaogames(Odin odin) {
		 this.odin = odin;
	}
}

di

Spring이 누군가의 역할을 해줍니다.

DI를 사용했을 때의 장점

kakaogames 클래스는 odin을 생성하는 로직이 필요 없습니다. (kakaogames의 일에 더 집중할 수 있음)

복잡한 의존 관계를 누군가가 잘 생성하고 관리해줍니다.

다형성을 활용하여 유연한 구조를 만들 수 있습니다. ex) Repository Interface

Spring에서의 DI 개념

스프링의 세가지 핵심 요소 중에서 IoC/DI가 있습니다.

스프링에게 제어권을 넘기면(IoC) 스프링이 DI를 해줍니다. (위의 예시에서 ‘누군가’의 역할)

Bean은 스프링 컨테이너에 생성된 객체를 지칭합니다. (kakaogames, odin)

스프링은 기본적으로 싱글톤방식으로 동작합니다. (odin이라는 Bean은 하나만 생성됨)

Spring에서 DI 사용법

스프링에서 DI를 사용하는 방법은 세가지가 있으나 주로 ‘생성자 주입’ 방법을 사용합니다.

생성자 주입 (Constructor Injection)

위의 예시와 같이 생성자로 주입하는 방식.

//Bean
class kakaogames {
	private final Odin odin;
	
	@Autowired // 생성자가 하나일 경우 생략 가능
	public kakaogames(Odin odin) {
		 this.odin = odin;
	}
}
  • Odin이 Bean이 아닐 경우 오류 발생
  • 생성자가 하나일 경우 @Autowired 생략 가능
//Bean
@RequiredArgsConstructor
class kakaogames {
	private final Odin odin;
}

Lombok을 사용할 경우 @RequiredArgsConstructor를 사용하면 생성자를 자동으로 생성해줍니다. (Dependency가 final로 선언되어 있어야 함)

  • Lombok이 생성자 생성
  • 생성자가 하나이므로 @Autowired 생략 가능

스프링은 생성자 주입을 권장합니다.

  • 필요한 의존성이 주입되지 않는 것을 컴파일타임에서 방지
  • 단위 테스트에 용이
  • 한번 주입된 의존성이 변경되지 않음을 보장 (final)
  • 순환참조 방지 (객체 생성 단계에서 의존성을 주입하기 때문)

필드 주입 (Field Injection)

변수 선언문에 @Autowired를 붙여주면 스프링이 DI를 해줍니다.

//Bean
class kakaogames {
	@Autowired
	private Odin odin;
}

가장 간단한 방식이라 예전에 많이 쓰였다고 합니다.

필드 주입의 문제점

  • 외부에서 변수 접근 불가 (단위 테스트 어려움)
  • 순환 참조 발생 가능

수정자 주입 (Setter Injection)

중간에 의존성을 변경해야 하는 경우 사용합니다. (거의 없음)

//Bean
class kakaogames {
	private Odin odin;
	
	@Autowired
	public setOdin(Odin odin) {
		this.odin = odin;
	}
}

수정자 주입의 문제점

  • 필드 주입과 마찬가지로 객체가 생성된 이후에 의존성이 주입되므로 순환 참조가 발생할 가능성이 있음
  • 의존성이 변경되지 않는다는 보장이 없음

필드 주입과 수정자 주입의 문제점들을 생성자 주입으로 대부분 해결할 수 있습니다.

스프링은 생성자 주입을 사용하는 것을 강력히 권장합니다. (다른 DI를 사용할 경우 경고 메시지 발생)

태그: ,

카테고리:

업데이트:

댓글남기기