본문으로 바로가기

[SPRING] DI, IoC

category SPRING/기본 상식 2021. 4. 12. 23:25

DI(Dependency Injection)

DI(Dependency Injection)란 스프링이 다른 프레임워크와 차별화되어 제공하는 의존 관계 주입 기능으로,

 

'객체를 직접 생성하는 게 아니라 외부에서 생성한 후 주입 시켜주는 방식' 이다.

 

DI(의존성 주입)를 통해서 모듈 간의 결합도가 낮아지고 유연성이 높아진다.

 

의존성 주입 세 가지 방법

 

- DI는 세가지 방법이 있습니다. 생성자 주입Setter 주입, 필드 주입이 있습니다 .

 

Field Injection (필드 주입)

- Bean으로 등록된 객체를 사용하고자 하는 클래스에 Field로 선언한 뒤 

  @Autowired키워드를 붙여주면 자동으로 주입  된다.

-  `@Autowired` 를 사용하는데 외부에서 변경이 불가능하여 테스트 하기 힘듭니다.

Method(Setter) Injection (Setter 주입)

- 선택, 변경 가능성이 있는 의존관계에 사용되며 스프링빈을 선택적으로 등록이 가능합니다.

- Setter Method에 @Autowired를 붙여서 DI를 구현하는 방식이다.

- 단일 책임의 원칙 위반 : 의존성 주입이 쉬움

- 불변성 : final을 선언할 수 없기 때문에 객체가 변할 수 있음

@Service
public class BoardService{
  private BoardDAO boardDao;
  
  @Autowired
  public void setBoardDao(BoardDao boardDao){
    this.boardDao = boardDao;
  }
}
// XML
<property name="myName" value="poodle"></property>

 

Constructor Injection (생성자 주입)

- 현재 가장 권장되고 있는 방법입니다. 

- 생성자 호출시점에 딱 1번만 호출되는 것을 보장한다.

- 불변, 필수 의존관계에 사용합니다. (private final 클래스명)

 

@Service
public class BoardService {

    private BoardDao boardDao;

    // @Autowired Spring 4.3 버젼 부터 @Autowired 생략가능
    public BoardService(BoardDao boardDao) {
        this.boardDao = boardDao;
    }
}

//XML
<constructor-arg ref = "cat"></constructor-arg>

 

UPGRADE! 여기서 Lombok이 적용 되면?

 

@Service
@AllArgsConstructor
// Immutability 이슈까지 해결하고 싶다면 ->  @RequiredArgsConstructor
public class BoardService {

    private BoardDao boardDao;

}

 

 

스프링에서는 객체를 Bean이라고 부르며, 프로젝트가 실행될때 사용자가 Bean으로 관리하는 객체들의 생성과 소멸에 관련된 작업을 자동적으로 수행해주는데 객체가 생성되는 곳을 스프링에서는 Bean 컨테이너라고 부른다.

 

중요! 생성자가 딱 1개만 있으면 @Autowired를 생략해도 자동 주입 된다. 물론 스프링 빈에만 해당한다.

 

 

 

Ioc(Inversion of Control)

IoC(Inversion of Control)란 "제어의 역전" 이라는 의미로, 말 그대로 

'메소드나 객체의 호출작업을 개발자가 결정하는 것이 아니라, 외부에서 결정되는 것을 의미'한다.

 

IoC는 제어의 역전이라고 말하며, 간단히 말해 "제어의 흐름을 바꾼다"라고 한다.

 

객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 중복, 유지 보수를 편하게 할 수 있게 한다.

 

기존에는 다음과 순서로 객체가 만들어지고 실행되었다.

  1. 객체 생성
  2. 의존성 객체 생성 (클래스 내부에서 생성)
  3. 의존성 객체 메소드 호출

하지만, 스프링에서는 다음과 같은 순서로 객체가 만들어지고 실행된다.

  1. 객체 생성
  2. 의존성 객체 주입
    스스로가 만드는것이 아니라 제어권을 '스프링에게 위임하여 스프링이 만들어놓은 객체를 주입'한다.
  3. 의존성 객체 메소드 호출

스프링이 모든 의존성 객체를 스프링이 실행될때 다 만들어주고 필요한곳에 주입시켜줌으로써 

Bean들은 싱글턴 패턴의 특징을 가지며, 제어의 흐름을 사용자가 컨트롤 하는 것이 아니라

스프링에게 맡겨 작업을 처리하게 된다.