❗DI(Dependency Injection)❗
- 스프링이 다른 프레임워크와 차별화되어 제공하는 의존 관계 주입기능
- 객체를 직접 생성하는 게 아니라 외부에서 생성한 후 주입 시켜주는 방식
- DI(의존성 주입)를 통해 모듈 간의 결합도가 낮아지고 유연성이 높아짐
🔻의존성이란?
public class Cook {
private Knife knife;
public Cook() {
knife = new Knife();
}
public void cook(Food food) {
knife.cut(food);
}
}
- cook class는 cook(Food food) 메소드를 실행 할 때, knife.cut() 을 위해 Knife class가 필요
-> 이러한 사항을 Cook class가 Knife에 의존성을 가지고 있다 라고 함.
- 의존성에 의한 문제점
- Unit Test가 어려워짐
- 내부에서 직접 생성하는 객체에 대해서 mocking을 할 방법이 없기때문...
- Code의 변경이 어려워짐
- Knife class 변경 시, Knife class에 의존하고 있는 Cook class도 변경 해줘야 함
🔸그래서 DI란~
1. 방법 1 : A객체가 B와 C객체를 New 생성자를 통해 직접 생성하는 방법
2. 방법 2 : 외부에서 생성된 객체를 setter()나 생성자를 통해 사용하는 방법
- 방법 2가 의존성 주입의 예시
- A객체에서 B, C 객체를 사용(의존)할 때 A객체에서 직접 생성하는 것이 아니라 외부(IOC 컨테이너)에서 생성된 B,C 객체를 조립(주입)시켜 setter 혹은 생성자를 통해 사용하는 방법
🎈 의존성 주입 예제
- 생성자를 통해 전달 받음
public class Cook {
private Knife knife;
public Cook(Knife knife) {
this.knife = knife;
}
}
public void setKnife(Knife knife) {
this.knife = knife;
}
📚나만의 정리
- 하나의 클래스 내부에서 다른 객체를 직접 생성(new 선언 등)해주는 것이 아닌, 외부에서 생성된 객체를 하나의 클래스에서 주입받는 것.
🔻Bean 컨테이너
- 스프링에서는 객체를 Bean 이라고 부름
- 스프링 IOC 컨테이너가 관리하는 객체, Spring IOC 컨테이너에 의해서 인스턴스화되고 조립 및 관리되는 객체
- 프로젝트가 실행될 때 사용자가 Bean으로 관리하는 객체들의 생성과 소멸에 관련된 작업을 자동적으로 수행해주는데 객체가 생성되는 곳을 스프링에서는 Bean 컨테이너라고 부름
🔻IOC Container(Spring Container)
- 사용자가 작성한 메타데이터(xml 파일 또는 @(어노테이션))에 따라 Bean 클래스를 생성 및 관리하는 Spring의 핵심 컴포넌트
❗IOC(Inversion of Control)❗
- "제어의 역전" 이라는 의미, 간단히 말해 "제어의 흐름을 바꾼다" 라고 함
- 메소드나 객체의 호출작업을 개발자가 결정하는 것이 아닌, 외부에서 결정되는 것을 의미
- 객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 중복, 유지 보수를 편하게 할 수 있게 함
- 스프링이 모든 의존성 객체를 스프링이 실행될 때 다 만들어주고 필요한 곳에 주입시켜줌
-> Bean들은 싱글턴 패턴의 특징을 가짐( 객체가 한번만 생성됨 )
- 제어의 흐름을 사용자가 컨트롤 하는 것이 아닌 스프링에게 맡겨 작업을 처리하게 됨
🔸그래서 IOC 란~
- 일반적으로 의존성에 대한 제어권은 객체 자기 자신이 갖음
<예제1>
- Sample class에서 Apple 객체를 불러옴
- 의존관계는 new 라는 키워드를 통해 생성됨
class Sample{
private Apple apple = new Apple();
}
<예제2>
- SampleTest class에서 Apple 객체를 생성한 뒤 Sample class의 생성자로 주입시켜줌
- Sample이 직접 Apple을 생성하는 것이 아니라 생성자로 주입 받음
class Sample{
private Apple apple;
public Sample(Apple apple) {
this.apple = apple;
}
}
class SampleTest{
Apple apple = new Apple();
Sample sample = new Sample(apple);
}
- <예제1>에서 Apple 객체의 제어권이 Sample에게 있었다면, <예제2>에서는 SampleTest에게 있음
- 이처럼 의존성을 역전시켜 제어권을 직접 갖지 않는 것을 IOC라고 하며, 의존성을 외부에서 주입시켜 주는 것을 DI라고 함
🔻@Bean, @Component 차이
- @Configuration 은 스프링 IOC Container에게 해당 클래스를 Bean 구성 Class임을 알려주는 것
- @Component는 개발자가 직접 작성한 class를 Bean으로 만드는 것
- @Component를 사용한 Bean의 의존성 주입은 @AutoWired 를 이용하여 할 수 있음
- @Bean은 개발자가 작성한 Method를 통해 반환되는 객체를 Bean으로 만드는 것
- 자세한 내용 여기 참고
🙆♀️참고🙆♂️
[Spring] DI, IoC 정리
Spring - Spring을 왜 사용하나요?(DI)
스프링(Spring) - DI(Depedency Injection) 개념과 예제[공부해서 남 주자]
[스프링] IoC(Inversion of Control), DI(Dependency Injection), Spring Container, Bean 정리