DI를 사용하는데 꼭 IoC가 필요한 것인지, 그렇지 않다면 IoC를 사용하지 않고
DI를 어떻게 구현할 수 있는 것인지 생긴 궁금증을 해소하던 과정을 작성한 내용입니다.
DI와 IoC를 이해하신걸로 가정하고 글이 진행되오니 이 점 양해부탁드립니다!!
DI란?
간단하게 설명하자면 DI(Dependency Injection)는 "의존성 주입" 이란 뜻을 가지며,
클래스 내부에서 다른 클래스의 메소드를 사용할 수 있습니다.
이를 통해 객체지향 프로그래밍에서 코드를 일종의 "도구"로써 가져와 사용할 수 있는 것입니다.
제가 궁금한 점을 보기 전 우리가 보통 사용하는 DI를 살펴보겠습니다.
@Requiredargsconstructor
public DependencyClass {
private final InjectionClass injectionClass;
}
위와 같이 DI를 사용하면 클래스 내부에 다른 클래스의 메소드를 사용하기 위해서
클래스 내부에 외부 클래스의 객체를 생성하는 것입니다.
DI 방법에는 다양한 방법이 있는데요, 위에선 세 가지 방법인 "필드 주입", "세터 주입" "생성자 주입"중 "생성자 주입" 을 사용하였습니다.
@Requiredargsconstructor : final로 선언된 필드들을 묶어 생성자로 만들어주는 것이다.
이제 의존성 주입을 위한 준비는 끝났습니다. 개발자는 의존성 주입을 할 때 위의 코드처럼 사용할 외부 클래스를 클래스 내부에 선언하고 사용하기만 하면 됩니다.
정말 간단하지 않나요? 😁
이렇게 간단하게 사용할 수 있는 이유는 바로 IoC가 있기 때문입니다.
IoC란?
IoC(Inversion of Control)의 뜻은 제어의 역전이란 뜻으로,
개발자가 프레임워크를 제어하는 것이 아닌 프레임워크가 개발자를 제어하는 것을 의미합니다
위 DI의 구현에서 IoC의 역할은 생성한 외부 클래스 객체를 빈으로 등록하여 내부 클래스에서 사용할 수 있게 합니다.
이렇게 개발자는 DI를 선언해서 외부 클래스 객체를 생성해 별도의 복잡한 설정과 초기화를 하지 않고도 외부 클래스 객체를 사용할 수 있는 것입니다.
하지만 동시에 IoC에 의존하게 되는 것이죠.
물론 의존한다는 것이 꼭 나쁘다는 뜻은 아니라, "왜 IoC에 의존하는 것일까?" 라는 생각이 들었습니다.
그래서 DI를 쓰려면 꼭 IoC가 필요한 것일까?
위 질문에 대한 정답은 "아니다" 입니다.
물론 내부 클래스에 외부 클래스 객체를 선언하는 것만으로 이외에 설정을 거치지 않고 외부 클래스 객체를 사용할 수 있다는 것은 매우 큰 이점입니다.
그렇기에 개발자는 "서비스 로직"에 집중할 수 있고, 나머지 프로그램 실행에 필요한 기본 설정은 프레임워크 단에서 처리해주므로 굉장히 효율적인 시스템입니다.
의존성 주입의 과정에서 IoC를 사용할 경우 굉장히 간편하게 설정이 완료되기 때문에
의존성 주입시에 IoC를 사용하는 것이지, DI에 꼭 IoC가 필요한 것은 아닙니다.
하지만 OOP의 장점(유지 보수, 확장성)들을 얻으려면 SOLID 원칙을 준수해야 합니다
그리고 DI/IoC는 이를 준수하기 위해 고안된 패턴이기에 대부분 사용하는 것입니다.
DI/IoC 대신으로 사용하긴 부족하지만, Pure DI도 존재하긴 합니다.
Pure DI
Pure DI는 클래스들의 빈 생성을 IoC에게 맡기는 것이 아닌 개발자가 직접 빈으로 등록하는 것입니다.
@Configuration
public class AppConfig {
@Bean
public DependencyClass dependencyClass() {
return new DependencyClass(injectionClass());
}
public InversionClass inversionClass() {
return new InversionClass(ControlClass());
}
}
장점
- 애플리케이션의 의존성 트리를 알 수 있습니다.
- 직관적입니다. (프레임워크에 맡길 경우 클래스 내부에 선언된 외부 객체를 보고 파악해야합니다)
- DI 컨테이너에 대한 공부를 따로 하지 않아도 됩니다 (DI 컨테이너를 쓰지 않는다는 전제)
단점
- 개발자가 수작업으로 한 클래스의 의존성이 추가/변경 될 때마다 코드 또한 추가/변경 해주어야 하기 때문에 매우 번거롭습니다.
- 프로젝트가 큰 경우에 더더욱 의존성 추가/변경에 대한 리소스가 증대되며, 유지보수가 까다로워 집니다.
사실 저도 DI/IoC를 엄청 편리하게 잘 쓰고 있는 입장이지만😊
그저 개발자로서 생긴 호기심이 저를 자극하여 이 글을 작성하게 되었습니다.
글의 짜임새가 어수선하고, 잘못된 내용이 있을 수 있습니다. 해당 부분을 알려주시면 바로 수정하도록 하겠습니다! :)
'Spring' 카테고리의 다른 글
[Spring] Spring Cache (0) | 2022.09.05 |
---|