Spring - DI, IOC

고 연우·2022년 9월 29일
0

SpringBoot

목록 보기
6/8

❗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;
    }
}   
  • setter를 통해 전달 받음
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 정리

0개의 댓글