IoC(제어의 역전)은
프로그램의 제어 흐름을 직접 제어하는 것이 아니라 외부에서 관리하는 것으로 코드의 최종호출은 개발자가 제어하는 것이 아닌 프레임워크의 내부에서 결정된 대로 이루어집니다.
의존성 주입은
객체가 다른 객체에 의존할 때 이를 외부에서 주입해주는 방식을 말합니다. 즉, 객체가 필요로 하는 의존성을 직접 생성하는 것이 아니라, 외부에서 생성된 객체를 주입해주는 것입니다.
DI는 대표적으로 스프링 프레임워크에서 지원하는 IoC의 형태로 클래스 사이의 의존관계를 빈 설정 정보를 바탕으로 컨테이너가 자동으로 연결해줍니다.
이때 스프링 컨테이너 ApplicationContext를 이용하여 설정 정보를 생성, 등록하고 필요한 객체를 생성자 혹은 setter 혹은 필드를 통해 주입합니다.
🍕피자 가게 요리사는 피자 레시피에 의존한다.
피자 레시피가 변화하게 되었을때
변화된 레시피에 따라서 요리사는 피자 만드법을 수정해야한다.
레시피의 변화가 요리사의 행위에 영향을 미쳤기 때문에 요리사는 레시피에 의존한다고 말할 수 있다.
만약 어떤 피자가게의 레시피는 피자가게 요리사가 아니라, 피자 가게 사장님이 정하는 상황을 상상해보자.
피자가게 요리사가 의존하고 있는 피자레시피는 외부(사장님)에서 결정하고 주입한느 것
생성자 삽입, Setter를 이용한 메소드 매개 변수 삽입, 필드 주입이 있습니다.
@Service
public class BurgerService {
private BurgerRecipe burgerRecipe;
@Autowired
public void setBurgerRecipe(BurgerRecipe burgerRecipe) {
this.burgerRecipe = burgerRecipe;
}
}
setter를 사용한 주입이다.
@Service
public class BurgerService {
@Autowired
private BurgerRecipe burgerRecipe;
}
변수 선업부에 @Autowired
어노테이션을 붙입니다.
@Autowired
를 사용하는데
@Configuration
같은 스프링 설정 목적으로 사용합니다.생성자 호출시점에 딱 1번만 호출되는 것을 보장하며 불변, 필수 의존관계에 사용합니다.
@Service
public class BurgerService {
private BurgerRecipe burgerRecipe;
@Autowired
public BurgerRecipe(BurgerRecipe burgerRecipe) {
this.burgerRecipe = burgerRecipe;
}
}
생성자에 @Autowired 어노테이션을 붙여 의존성을 주입받을 수 있으며, 가장 권장되는 주입 방식이다.
DI를 사용하면 객체 간의 결합도를 낮출 수 있습니다. 객체 간의 결합도가 낮아지면 코드의 유지보수성과 확장성이 개선됩니다.
DI를 사용하면 테스트 용이성이 높아집니다. 의존하는 객체를 모의(mock) 객체로 대체하여 테스트할 수 있습니다. 이는 의존하는 객체가 아직 구현되지 않았더라도 테스트를 진행할 수 있게 해줍니다.
DI를 사용하면 객체 간의 의존성이 명시적으로 표현되므로, 재사용성이 높아집니다. 의존성을 주입하는 방식으로 객체를 조립할 수 있으므로, 동일한 의존성을 가지는 객체를 생성할 때 코드의 중복을 줄일 수 있습니다.
DI를 사용하면 의존성을 관리하는 책임을 DI 컨테이너에게 위임하므로, 코드의 유지보수성이 개선됩니다. 의존성이 변경되더라도 DI 컨테이너에서 의존성을 관리하기 때문에, 변경이 필요한 코드를 수정하는 일을 줄일 수 있습니다.
DI를 사용하면 객체를 동적으로 생성하고 의존성을 주입할 수 있으므로, 유연성이 높아집니다. 객체 생성 방식이 변경되더라도, DI 컨테이너에서 객체를 생성하고 의존성을 주입하므로, 코드 수정이 필요하지 않습니다.
이러한 방식을 적용하면 객체 간의 결합도를 낮출 수 있으며, 유지보수성, 확장성, 테스트 용이성 등을 개선할 수 있습니다. 또한 의존성을 관리하는 책임을 전적으로 DI 컨테이너에게 위임함으로써 코드의 중복을 줄이고, 유연하고 모듈화된 코드를 작성할 수 있습니다.
예를 들어 호텔클래스와 룸 클래스가 있을때 룸 클래스는 호텔클래스에 의존성이 생기게 되는데, 이때 DI를 사용하여 룸 클래스에서 호텔클래스의 인스턴스를 매개변수로 사용하여 주입받으면 의존성을 제거하여 유지 보수가 간결 해집니다.