이전 게시글에서 스프링을 정의해 봤다.
https://hyerin6.github.io/2021-09-24/spring/
IoC/DI, AOP, PSA, POJO 등 다양하고 익숙한 단어들이 많이 나왔는데
사실 Spring 공부를 시작하고 토비의 스프링을 읽으면서 다음 게시글에서 정리해 본 적이 있다.
- Ioc/DI: https://hyerin6.github.io/2020-01-31/spring-DI-IoC/
- AOP: https://hyerin6.github.io/2020-02-14/spring-AOP/
그러나 단어 의미나 구현 방법 위주로 정리했기 때문에
처음부터 다시 꼼꼼하게 알아보기로 했다.
IoC란?
애플리케이션 코드를 작성할 때, 특정 기능이 필요하면 라이브러리를 사용한다.
이때 프로그램의 흐름을 제어하는 주체가 애플리케이션 코드이다.
하지만 프레임워크 기반의 개발에서는 프레임워크 자신이 흐름을 제어하는 주체가 되어
필요할 때마다 애플리케이션 코드를 호출하여 사용한다.
프레임워크에서 이 젱권을 가지는 것이 바로 컨테이너이다.
객체의 생성부터 생명주기 관리까지의 모든 것을 컨테이너가 맡아서 하게 된다.
이를 일반적인 제어권의 흐름이 바뀌었다고 해서 IoC (Inversion of Control, 제어의 역전) 라고 한다.
IoC 사용 목적
(1) 클래스 호출 방식
클래스 내에 선언과 구현이 같이 있기 때문에 다양한 형태로 변화가 불가능하다.
(2) 인터페이스 호출 방식
클래스와 인터페이스를 상속받아 구현하는 클래스로 분리한다.
구현 클래스 교체가 용이하여 다양한 변화가 가능하다.
그러나 구현 클래스 교체 시 호출 클래스의 코드에서 수정이 필요하다.
→ 부분적으로 종속적이다.
(3) 팩토리 호출 방식
팩토리 방식은 팩토리가 구현 클래스를 생성하기 때문에 호출 클래스는 팩토리를 호출하는 코드로 충분하다.
구현 클래스 변경 시 팩토리만 수정하면 되기 때문에 호출 클래스에는 영향을 미치지 않는다.
그러나 호출 클래스에서 팩토리를 호출하는 코드가 들어가야 하는 것 또한 팩토리에 의존함을 의미한다.
(4) IoC
팩토리 패턴의 장점을 더해 어떠한 것에도 의존하지 않는 형태가 되었다.
실행 시점에 클래스간 관계가 형성된다.
즉 의존성이 삽입된다는 의미로 IoC를 DI라는 표현으로도 사용한다.
위 그림에서 화살표 방향이 바뀐 것에 주목해보자.
클래스가 팩토리를 호출하던 팩토리 패턴의 구조에서 클래스에 의존성 삽입하는 구조로 바뀌었다.
스프링을 사용하지 않으면?
- 오브젝트의 생명주기 문제
- 부품화 문제
- 기술 은닉과 부적절한 기술 은닉 문제
위 문제를 해결하지 못하면 웹 애프리케이션은 리소스를 잘 이용하지 못하고,
테스트, 확장, 변경이 어려워질 것이다.
Spring은 이러한 문제를 해결하기 위해 만들어진 컨테이너라고 볼 수도 있다.
- 오브젝트의 생명주기 문제 → DI 컨테이너로 해결
- 부품화 문제 → DI 컨테이너로 해결
- 기술 은닉과 부적절한 기술 은닉 문제 → AOP로 해결
DI
IoC는 DI(Dependency Injection)라고도 부른다.
DI는 오브젝트를 생성하고 오브젝트끼리의 관계를 생성해 소프트웨어의 부품화 및 설계를 가능하게 한다.
DI를 이용하면 인터페이스 기반의 컴포넌트를 쉽게 구현할 수 있다.
DI는 의존 관계의 주입이라는 뜻이다.
오브젝트 사이의 의존관계를 만드는 것이다.
클래스에서 new 연산자가 사라짐으로써 개발자가 팩토리 메서드 같은 디자인 패턴을 구현하지 않아도 DI 컨테이너가 건내주는 인스턴스를 인터페이스로 받아 인터페이스 기반의 컴포넌트화를 구현할 수 있게 되었다.