Spring - IoC와 DI

김상엽·2024년 1월 26일
0

Spring

목록 보기
6/26
post-thumbnail

TIL

IoC와 DI

IoC(제어의 역전)

스프링과 같은 프레임워크를 사용할 때를 생각해보자. Controller, Service 같은 객체들의 동작을 우리가 직접 구현하기는 하지만, 해당 객체들이 어느 시점에 호출될 지는 신경쓰지 않는다. 단지 프레임워크가 요구하는대로 객체를 생성하면, 프레임워크가 해당 객체들을 가져다가 생성하고, 메서드를 호출하고, 소멸시킨다. 프로그램의 제어권이 역전된 것이다.

IoC라는 개념을 도입함으로써 무엇을 얻을 수 있을까?

  • 프로그램의 진행 흐름과 구체적인 구현을 분리시킬 수 있다.
  • 개발자는 비즈니스 로직에 집중할 수 있다.
  • 구현체 사이의 변경이 용이하다.
  • 객체 간 의존성이 낮아진다.

DI(의존성 주입)

DI는 IoC라는 개념을 구현하기 위해 사용하는 디자인 패턴 중 하나로, 이름 그대로 객체의 의존관계를 외부에서 주입시키는 패턴을 말한다. 의존성 주입에는 세 가지 주요 스타일이 있다. 생성자 주입, 세터 주입, 인터페이스 주입이다.

생성자 주입(Constructor Injection)

public class A {
    private B b;

    public A(B b) {
        this.b = b;
    }
}

Setter 주입(Setter Injection)

public class A {
    private B b;

    public void setB(B b) {
        this.b = b;
    }
}

인터페이스 주입(Interface Injection)

public interface BInjection {
    void inject(B b);
}

public A implements BInjection {
    private B b;

    @Override
    public void inject(B b) {
        this.b = b;
    }
}

DI를 사용하면 어떤 장점이 있을까?

  • 의존성이 줄어든다. (변경에 덜 취약해진다.)
  • 모의 객체를 주입할 수 있기 때문에 단위 테스트가 쉬워진다.
  • 가독성이 높아진다.
  • 재사용성이 높아진다.

IoC Container와 Bean

Spring IoC 컨테이너

IoC Container는 오브젝트의 생성과 관계설정, 사용, 제거 등의 작업을 대신 해준다하여 붙여진 이름이다. 이때, IoC Container에 의해 관리되는 오브젝트들은 Bean 이라고 부른다.

Bean

Spring이 관리하는 객체이다. 사용하는 방법은 다음과 같다.

  • @Component : Bean으로 등록하고자하는 클래스 위에 설정한다.
  • @ComponentScan : @ComponentScan에 설정해 준 packages 위치와 하위 packages 들을 전부 확인하여 @Component가 설정된 클래스들을 Bean으로 등록 해준다.
  • @Autowired
    • 필드 위에 @Autowired : Spring에서 IoC 컨테이너에 저장된 memoRepository Bean을 해당 필드에 DI 즉, 의존성을 주입 해준다.
    • 메서드 위에 @Autowired : 객체의 불변성을 확보할 수 있기 때문에 일반적으로는 생성자를 사용하여 DI하는 것이 좋다.

ApplicationContext

  • ApplicationContext는 BeanFactory등을 상속하여 기능을 확장한 Container 이다.
    • BeanFactory는 ‘Bean’ 의 생성, 관계설정등의 제어를 담당하는 IoC 객체이다.
  • IoC 컨테이너에서 Bean을 수동으로 가져오는 방법
  • 'Bean' 이름으로 가져오기
public MemoService(ApplicationContext context) {
MemoRepository memoRepository = (MemoRepository) context.getBean("memoRepository");
  • 'Bean' 클래스 형식으로 가져오기
MemoRepository memoRepository = context.getBean(MemoRepository.class);

오늘의 회고

어제는 병원에 가서 공가처리를 하였다. 하루 쉬고 다시 공부를 하니까 기억이 잘 안나서 복습을 하고 강의를 들으니 그렇게 많이 진도를 나가지는 못했다. 이번주는 주말까지해서 입문주차강의를 끝내야겠다.

profile
개발하는 기록자

0개의 댓글