| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | 7 |
| 8 | 9 | 10 | 11 | 12 | 13 | 14 |
| 15 | 16 | 17 | 18 | 19 | 20 | 21 |
| 22 | 23 | 24 | 25 | 26 | 27 | 28 |
| 29 | 30 | 31 |
- 클래스 로더 계층
- 파이썬
- 어플리케이션 클래스 로더
- 파이썬 문자열 메서드
- 파이썬 리스트 메서드
- python list method
- 딕셔너리
- getreference
- 스프링 컨테이너
- 플랫폼 클래스 로더
- stop the world
- 스프링
- 심볼릭 레퍼런스
- Spring
- aws saa-c03
- 자료구조
- java
- 코딩테스트
- 2026 AWS SAA-C03
- 객체지향
- 자바
- python
- 알고리즘
- AWS SAA-C03 합격후기
- 부트스트랩 클래스 로더
- 컴포넌트 스캔
- 다이렉트 레퍼런스
- 백준
- BFS
- dfs
- Today
- Total
클라우드 낚시꾼
[Spring] IoC, DI와 스프링 컨테이너(Spring Container) 본문
이 글에서는 IoC(제어의 역전), DI(의존관계 주입)으로 스프링 컨테이너를 이해해 볼 것이다. 차근 차근 알아가보자.
1. IoC(Inversion of Control, 제어의 역전)
IoC란 프로그램의 흐름이 외부에서 제어되는 것을 뜻한다. 이것을 라이브러리와 프레임워크의 차이로 이해해보자. JAVA를 사용하다보면 Scanner, List 등과 같이 유용한 기능을 제공하는 java.util 라이브러리를 사용하게 된다. 우리가 이 라이브러리를 사용했을 때 코드의 제어는 누가 가져가는가? 개발자가 가져간다. 라이브러리를 사용하더라도 코드의 실행 흐름은 개발자가 꾸민대로 진행된다.
다음으로, 우리가 Spring 프레임워크를 사용할 때를 생각해보자. 우리는 Spring이라는 Frame에 맞춰 작업을 한다. 즉, 내 코드의 실행이 Spring에 의해 제어될 것을 감안하고 로직을 작성한다. 이것이 제어의 역전, IoC이다.
2. DI(Dependency Injection, 의존관계 주입)

의존관계는 정적인 클래스 의존 관계, 실행 시점에 결정되는 동적인 객체(인스턴스) 의존 관계 둘을 분리해서 알아보자.
정적인 클래스 의존관계
위 코드에서 빨간색 영역을 집중해보자. 빨강 영역은 코드만 봐도 memberRepository가 어떤 객체를 의존하고 있는 지 알 수 있다. 이처럼 코드 실행 없이 코드 자체로 의존 관계를 알 수 있는 것을 정적인 클래스 의존관계라고 한다.
동적인 객체 인스턴스 의존 관계와 의존관계 주입
위 코드에서 초록색 영역에 집중해보자. 초록 영역은 코드만 봐서는 memberRepository에 어떤 객체가 주입될 지 알 수 없다. 왜냐하면, 코드를 실행시키고 나서야 memberRepository에 객체가 주입되기 때문이다. 동적인 객체 인스턴스 의존 관계를 의존관계 주입이라고 표현한다. 의존관계 주입을 사용하게 되면 클라이언트의 코드 변경 없이 의존 관계를 변경할 수 있다는 장점이 있다.
3. IoC 컨테이너, DI 컨테이너

위 AppConfig는 객체를 생성하고 관리하며 의존관계를 연결해주는 역할을 담당한다.

위 OrderServiceImpl(주문 서비스) 클라이언트 코드는 외부에 존재하는 AppConfig와 같은 구성자 의해 객체를 전달 받아서 멤버 변수를 초기화 할 것이다. 즉, OrderServiceImpl를 생성하는 코드가 실행되고 나서야 memberService와 discountPolicy에 실제 객체가 주입된다. AppConfig처럼 객체를 생성하고 관리하여 의존 관계를 주입하는 것을 IoC, DI 컨테이너라고 한다.
4. 스프링 컨테이너(Spring Container)
이제 스프링 컨테이너의 정체를 밝힐 시간이다. 스프링 컨테이너는 앞서 작성한 IoC, DI 컨테이너인 AppConfig와 거의 똑같다. 즉, 스프링 컨테이너도 IoC, DI 컨테이너다. 과거에는 직접 AppConfig 처럼 IoC, DI 컨테이너를 개발자가 만들어서 의존관계를 주입했다면, 최근에는 스프링 컨테이너 덕분에 더 편리하게 의존관계 주입을 할 수 있게 되었다. AppConfig를 스프링 컨테이너로 수정하면서 더 자세히 알아보자.

클래스에 @Configuration 어노테이션를 사용하면 해당 클래스를 스프링 컨테이너로(DI, IoC 컨테이너) 선언할 수 있다. 메서드에 @Bean 어노테이션을 사용하면 메서드가 반환하는 객체가 컨테이너에 스프링 빈으로 등록된다. 스프링 빈은 기본적으로 싱글톤으로 등록된다. 다음으로는 스프링 컨테이너를 사용하는 예시를 알아보자.

위 그림은 스프링 컨테이너의 구성을 추상화한 것이다. 빈 이름은 메서드 이름이고 이에 대응되는 빈 객체는 메서드가 반환한 객체이다. 빈 이름은 직접 부여될 수도 있다. 단, 각 빈들이 구별되기 위해서 빈 이름이 중복되어서는 안된다.

위 그림은 스프링 컨테이너가 설정 정보를 참고해서 스프링 빈 사이에 의존관계를 주입(DI)하는 것을 보여준다. 이렇게 자바 코드로 스프링 빈을 등록하면 생성자를 호출하면서 의존관계 주입도 한번에 처리된다. (빈의 등록과 의존 관계가 코드 한 줄로 한 번에 처리되다니 굉장히 효율적이다.)
5. 스프링 컨테이너(Spring Container) 사용하기

위의 코드는 스프링 컨테이너를 사용하는 코드의 일부분이다. 먼저 ApplicationContext는 스프링 컨테이너이다. AnnotationConfigApplicationContext에 @Configuration 어노테이션을 붙인 클래스를 전달하면, 이를 컨테이너 설정 클래스 정보로 인식한다. 컨테이너 설정 정보에 있는 메서드들의 반환 객체들을 스프린 빈으로 등록하면서 스프링 컨테이너를 생성한다. 그리고 이 스프링 빈은 스프링 컨테이너가 제공하는 getBean 메서드를 통해서 사용할 수 있다.
참고) 컨테이너 설정 클래스 정보로 JAVA뿐만 아니라 XML, Groovy도 가능하다. 즉, 스프링은 다양한 설정 형식을 지원한다. (물론, 최근에는 거의 JAVA만 사용한다고 한다.)
5. 마치며... (+출처)
아직까지는 스프링 컨테이너로 IoC, DI 컨테이너를 만들든 직접 코딩해서 만들든 차이가 없다고 느낄 수 있다. 하지만, 후에 스프링 컨테이너를 공부하면 할 수록 스프링 컨테이너로 IoC, DI 컨테이너를 만드는 게 얼마나 매력적인지 알 수 있게 될 것이다.
스프링 핵심 원리 - 기본편 강의 - 인프런
스프링 입문자가 예제를 만들어가면서 스프링의 핵심 원리를 이해하고, 스프링 기본기를 확실히 다질 수 있습니다., 스프링 핵심 원리를 이해하고, 성장하는 백엔드 개발자가 되어보세요! 📢
www.inflearn.com
'BE Framework > SpringBasic' 카테고리의 다른 글
| [Spring] 컴포넌트 스캔과 스프링 빈 자동 주입 (0) | 2024.03.16 |
|---|---|
| [Spring] @Configuration과 CGLIB (0) | 2024.03.14 |
| [Spring] 싱글톤 패턴과 싱글톤 컨테이너 (0) | 2024.03.13 |
| [Spring] 스프링 빈에 대하여 (BeanDefinition + 스프링 빈 조회) (0) | 2024.03.12 |
| [Spring] 객체 지향 설계 원칙 SRP, DIP, OCP와 관심사의 분리 (0) | 2024.03.12 |