우당탕탕

[Spring] IoC(Inversion of Control)과 DI(Dependency Injection) 이란? 본문

Tech/Spring

[Spring] IoC(Inversion of Control)과 DI(Dependency Injection) 이란?

모찌모찝 2022. 9. 1. 07:00
IoC와 DI란?


스프링을 사용하면 IoC와 DI라는 단어를 많이 듣게 된다.
IoC와 DI는 뭘까??

IoC(Inversion of Control)란?

IoC란 영어 그대로 제어의 역전이라 부른다.
제어의 역전이란 메서드나 객체의 호출 작업을 개발자가 아닌 스프링에게 제어권을 넘기는 것을 말한다. 
이전까지는 개발자가 객체의 생성을 관리하며 제어했지만, 스프링을 사용하게 되면 스프링 컨테이너에게 제어권을 넘겨 스프링 컨테이너가 흐름을 제어하게 된다.

 

DI(Dependency Injection)란?

DI란 의존성 주입이라 부르며, 객체를 직접 생성하는 게 아닌 외부(IOC 컨테이너)에서 생성한 후 주입시켜주는 방식이다.

의존성 주입 방식으로는 3가지 방법이 존재한다

  • 생성자 주입 ( Constructor Injection )
  • 수정자 주입 ( Setter Injection)
  • 필드 주입 ( Field Injection )

이 중에서 스프링에서 권장하는 의존성 주입 방법은 생성자 주입 ( Constructor Injection )이다.
왜 생성자 주입을 권장할까?
일단 각각의 주입에 대해 살펴보자

생성자 주입 ( Constructor Injection )

생성자 주입이란 생성자를 통해 의존관계를 주입하는 방법으로 생성자를 호출 시에 딱 한 번만 호출되는 것을 보장한다.
스프링 4.3 버전 이후라면 @Autowired를 생략해도 주입이 되며, 주입받는 필드에 final 키워드를 사용함으로써 주입돼야 하는 것을 보장한다.
아래는 예시 코드이다. 

@Controller
public class TestController {
	private final TestService testService;
    
    public TestController(TestService testService){
    	this.testService = testService;
    }
}

 

 

수정자 주입 ( Setter Injection)

수정자 주입이란 영어 그대로 setter를 사용하여 의존관계를 주입하는 방법이다. 수정 가능성이 존재하는 의존관계일 때 사용하며 자바 빈 프로퍼티 규약의 setter메서드 방식을 사용한다.
수정자 주입의 경우 final 키워드 선언이 불가능하며, setter 메서드에 @Autowired를 붙여 사용한다.

@Controller
public class TestController {
	private TestService testService;
    
    @Autowired
    public void setTestService(TestService testService){
    	this.testService = testService;
    }
}

 

필드 주입 ( Field Injection )

필드 주입이란 필드에 직접 의존관계를 주입하는 방법이다.
이는 코드가 짧아지는 장점이 있지만 외부에서 변경이 불가능하고 테스트 코드를 작성하기 힘들다는 단점이 존재한다.
또한 final 키워드 선언이 불가능해지고 의존관계를 파악하기 힘들어진다. 

 

@Controller
public class TestController {
	@Autowired
	private TestService testService;
}

필드 주입의 경우에도 Springboot 2.6 기준으로 순환 참조 방지가 된다. 
순환 참조에 대한 내용을 설명한 링크를 하나 첨부한다. https://ch4njun.tistory.com/269

세 가지의 의존성 주입에 대해 알아보았는데 왜 생성자 주입을 추천하는 것일까?
생성자 주입이 가지는 장점은 다음과 같다.

  • 의존관계 설정이 되지 않으면 컨파일 타임에 알 수 있다.
  • 의존성 주입이 필요한 필드를 final 키워드로 선언 가능하다
  • 스프링에서 순환 참조 감지 기능을 제공하며 순환 참조 시 에러를 보여준다.
  • 테스트 코드 작성이 용이하다.

Reference

Comments