[Spring] IoC/DI

사과알러지·2024년 3월 7일
0

Spring

목록 보기
1/5
post-custom-banner

IoC와 DI에 대해 항상 헷갈렸던 것 같아
정확한 개념을 정리해보려 한다.


IoC와 DI의 관계

IoC는 코드 간 결합도를 낮추고 유지보수성을 증가시키기 위한 원칙(Principle)이고 DI는 이를 구현하려는 디자인 패턴이다.

Inversion Of Control

우리 말로 번역하면 제어의 역전 정도가 되겠다.

Don't call us, we will call you.

  • 헐리우드 원칙(Hollywood Principle)

이러한 원칙을 프로그래밍에 적용하게 되면,

저수준 구성요소는 고수준 구성요소를 호출할 수 없게 되고

고수준 구성요소가 필요할 때 저수준을 호출하게 된다.

IoC는 메소드나 객체의 호출을 개발자가 결정하는 것이 아니라 외부에서 결정하자는 원칙이다

특히 스프링 프레임워크가 이를 관리하며 의존성 객체를 생성해
필요한 곳에 주입시켜주는 방식을 취한다.

💡 프레임워크와 라이브러리의 차이점

프레임워크는 라이브러리의 메소드를 적절한 시점에서 호출해 사용하도록 돕는다.

즉 라이브러리는 단순 활용가능한 도구들의 집합이고,
이에 대한 제어를 외부로 돌리는 IoC가 적용된 것이 프레임워크이다.


Dependency Injection

의존성 주입은 IoC를 실현하기 위한 디자인 패턴이다.

IoC의 하위 개념으로 생각할 수 있겠다.

DI를 적용하므로써, 객체 간 결합도를 줄이고 확장성을 높힐 수 있다.

대표적으로 세 가지 방식으로 DI를 구현한다.

// 1. setter를 통한 주입
@Service
public class TestService {
    private final List<Test> testList;
    
    @Autowired
    public void setTests(List<Test> tests) {
        this.testList = tests;
    }
    ...
}

// 2. 생성자를 통한 주입
@Service
public class TestService {
    private final List<Test> testList;

    @Autowired
    public TestService(List<Test> testList) {
        this.testList = testList;
    }
	...
}

// 3. 필드 주입
@Service
@RequiredArgsConstructor
public class TestService {
    
    @Autowired
    private final List<Test> testList;
	...
}

이 중 가장 권장되는 방식은 생성자를 통한 주입이다.

먼저 필드 주입은 IDE에서도 WARNING을 발생시킨다.

외부에서 변경이 불가능해 테스트하기 어렵다는 단점이 있기 때문이다.


setter를 통한 방식도 잘 사용되지 않는다.

의존관계를 변경될 수 있기 때문이다.
대부분의 의존관계는 애플리케이션 종료 전까지 변할 일이 없으며,
setter를 통한 주입을 하려면 public 메서드로 선언해야하는데,
변경하면 안되는 것을 접근할 수 있게 두는 것은 좋은 설계가 아니다.


그래서 생성자 주입을 사용한다.

객체를 생성할 때 딱 1번만 호출되고 이후에 호출되는 일이 없으므로 불변하게 설계할 수 있으며, 생성자에 원하는 객체를 넘겨 의존관계를 객체를 생성하며 다양하게 설정할 수 있다.

profile
노는 건 쉽고 코딩은 어려워
post-custom-banner

0개의 댓글