일러두기
- 토비의스프링3.1 Vol.1을 읽고 정리한 글입니다.
- 책을 이미 읽으신 분이 빠르게 훑으며 복습하는 용도로 보시면 좋을 것 같습니다.
- 임의로 핵심만 간추렸습니다. 책과 설명하는 순서가 바뀌거나 장/절 목차 이름이 바뀌거나 아예 빠진 내용이 많습니다.
1 IoC(제어의 역전)
제어의 역전(IoC; Inversion of Control)
오브젝트 팩토리
UserDaoTest의 개선 ✨
- 어떤 ConnectionMaker를 사용할지 결정하는 기능을 엉겁결에 떠맡았다
- 원래 UserDaoTest는 UserDao의 기능이 잘 동작하는지 테스트하려고 만든 것인데
UserDao에서 분리시킬 기능
- UserDao와 ConnectionMaker 구현 클래스의 오브젝트 만들기
- 그렇게 만든 두 오브젝트 관계 맺어주기
팩토리
- 분리시킬 기능을 담당할 클래스
- 객체의 생성 방법을 결정하고 만들어진 오브젝트를 돌려주는 역할
설계도로서의 팩토리
- UserDao: 핵심적인 데이터 로직을 맡는다
- ConnectionMaker: 핵심적인 기술 로직을 맡는다
- DaoFactory
- UserDao, ConnectionMaker 두 오브젝트를 구성하고 그 관계를 정의하는 책임을 맡는다
- 컴포넌트의 구조와 관계를 정의하는 설계도 같은 역할을 하는 것이다
생성할 DAO가 많아지면 발생하는 문제
- 중복이 발생한다
- ConnectionMaker 구현 클래스의 오브젝트를 생성하는 코드의 중복
오브젝트 생성 코드의 분리 ✨
제어권의 이전을 통한 제어의 역전
제어의 역전이란
- 프로그램의 제어 흐름 구조가 뒤바뀌는 것
- 일반적 흐름
- 사용하는 쪽에서 제어하는 구조
- 프로그램이 시작되고
- 사용할 오브젝트를 결정하고
- 결정한 오브젝트를 생성하고
- 만들어진 오브젝트에 있는 메서드를 호출하고
- 그 메서드 안에서 다음에 사용할 것을 결정하는 식
- 제어의 역전 시 흐름
- 자신이 사용할 오브젝트를 스스로 선택하지 않는다
- 생성하지도 않는다
- 자신도 어떻게 만들어지고 어디서 사용되는지 알 수 없다
- 모든 제어 권한을 자신이 아닌 다른 대상에게 위임한다!
제어의 역전의 예시
- 서블릿
- 템플릿 메서드 패턴
- 추상메서드 getConnection
- 이 메서드가 언제 어떻게 사용될지 자신은 모른다
- 프레임워크
- 라이브러리
- 동작하는 중에 필요한 기능이 있을 때 능동적으로 라이브러리를 사용한다
- 프레임워크는 거꾸로 프레임워크가 애플리케이션 코드를 사용한다
- 프레임워크 위에 개발한 클래스를 등록
- 프레임워크가 흐름을 주도하는 중
- 개발자가 만든 코드를 사용하도록 만드는 방식
- DaoFactory
- Connection의 구현 클래스를 결정하고 오브젝트를 만드는 제어권을 가진다
제어의 역전을 위해 필요한 것
- 컴포넌트의 생성, 관계설정, 사용, 생명주기 관리 등을 관장하는 존재가 필요하다
- IoC 컨테이너, IoC 프레임워크라고 부른다
- 스프링이 바로 IoC를 극한까지 적용하고 있는 프레임워크다.
- 우리가 만든 DaoFactory는 가장 단순한 IoC 컨테이너 또는 IoC 프레임워크라고 불릴 수 있다
2 스프링 IoC
애플리케이션 컨텍스트=빈 팩토리
- 이것이 스프링의 핵심을 담당한다
- DaoFactory가 하는 일을 좀 더 일반화한 것이다
오브젝트 팩토리를 이용한 스프링 IoC
빈
- 스프링이 제어권을 가지고
- 제어의 역전이 적용된 오브젝트
빈 팩토리
- 빈의 생성/관계설정 등의 제어를 담당하는 IoC 오브젝트
애플리케이션 컨텍스트
- IoC 방식을 따라 만들어진 일종의 빈 팩토리
빈 팩토리 vs 애플리케이션 컨텍스트 용어 차이
- 기본적으로 같은 대상을 가르킨다고 봐도 무방하다.
- 어디에 더 중점을 둬서 말하느냐의 차이다
- 빈 팩토리
- 빈을 생성하고, 관계를 설정하는
- IoC의 기본 기능에 초점을 맞추어 부르는 용어
- 애플리케이션 컨텍스트
- 애플리케이션 전반에 걸쳐 모든 구성요소의 제어작업을 담당하는
- IoC 엔진이라는 의미를 좀 더 부각하여 부르는 용어
DaoFactory를 스프링 빈 팩토리로 등록하기 ✨
- 아직까지는 오히려 좀 더 번거로운 준비 작업과 코드가 필요하다
- 아직까지는 DaoFactory와 기능적으로 다를 바 없다
애플리케이션 컨텍스트
구조
- ApplicationContext 인터페이스와
- BeanFactory 인터페이스를 상속한다
동작방식
- IoC를 적용해 관리할 모든 오브젝트에 대한 생성과 관계설정을 담당한다
- 생성정보와 연관관계 정보를 별도의 설정정보를 통해 얻는다
- 때로는 외부의 오브젝트 팩토리에 그 작업을 위임한다
- 바로 위에서 DaoFactory에 위임하게끔 하는 설정을 해봤다.
@Configuration이 붙은 DaoFactory
- 애플리케이션 컨텍스트가 활용하는 IoC 설정정보로 쓰인다
- @Bean이 붙은 메서드의 이름을 가져와 구성할 빈의 목록을 만든다
애플리케이션 컨텍스트 사용의 장점
- 클라이언트는 구체적인 팩토리 클래스를 알 필요가 없다
- 종합 IoC 서비스를 제공해준다
- 오브젝트가 만들어지는 방식을 다르게 가져가기
- 오브젝트를 효과적으로 활용할 수 있는 다양한 기능 제공
- 자동생성, 오브젝트에 대한 후처리, 정보의 조합
- 설정 방식의 다변화, 인터셉팅
- 빈을 검색하는 다양한 방법을 제공한다
- getBean()
- 빈의 이름으로 빈 찾기
- 타입으로 빈 검색하기
- 특정 어노테이션이 달린 빈 검색하기
3 IoC와 의존관계 주입
IoC 컨테이너
- 객체 생성/관계 맺어주는 등의 작업을 담당하는 기능을 일반화한 것
IoC라는 용어
의존관계 주입
- 의존관계 주입(DI; Dependency Injection)
- 스프링이 제공하는 IoC(제어의 역전)의 핵심을 짚어주는 용어
- 스프링을 DI 컨테이너라고도 부른다
의존관계
- 두 개의 클래스 또는 모듈이 의존관계에 있다고 말할 때는 항상 방향성을 부여해줘야 한다
- 의존한다는 것은
- B의 기능이 추가/변경되면
- 그 영향이 A로 전달된다는 것
- 대표적인 예
- A에서 B 객체에 정의된 메서드를 호출해서 사용
UserDao의 의존관계
- UserDao가 ConnectionMaker에 의존하고 있는 관계다
- ConnectionMaker 인터페이스가 변하면 영향받는다
- 하지만 인터페이스를 구현한 클래스에 의해서는 영향받지 않는다
- = 느슨한 결합
의존관계 주입은
- 클래스 모델/코드에는 런타임 시점의 의존관계가 드러나지 않는다
- 런타임 시점의 의존관계는 컨테이너나 팩토리 같은 제3의 존재가 결정한다
- 의존관계는 사용할 오브젝트에 대한 레퍼런스를 외부에서 제공해줌으로써 만들어진다
의존관계의 핵심
- 설계 시점에는 알지 못했던 두 오브젝트의 관계를 맺도록 도와주는 제3의 존재
- DaoFactory, IoC 컨테이너
UserDao의 의존관계 주입
- 제3의 존재: DaoFactory가 DI를 해줌
- 오브젝트의 생성, 초기화, 제공 등의 작업을 수행한다
- DI 컨테이너라고 불러도 됨
의존성을 주입해줬다고 다 DI는 아니다
- 다이나믹하게 구현 클래스를 결정해 제공받을 수 있어야 DI다
- 특정 구현 클래스로 고정되어있다면 DI가 아니다
- UserDao는 DConnectionMaker라는 특정 구현 클래스가 아닌
- ConnectionMaker라는 인터페이스에 의존함으로써
- ConnectionMaker 인터페이스를 구현한 여러 구현클래스들을 사용할 수 있다
장점
- 결합도가 낮다
- 변경을 통한 다양한 확장 방법에 자유롭다
의존관계 주입의 응용
기능 구현의 교환
- 로컬 디비 -> 운영 디비 구현 클래스 교체가 간편하다
- DAO 클래스의 코드를 수정할 필요 없이
- DaoFactory의 빈 등록 코드만 변경하면 된다
부가기능 추가
- DB 연결횟수 카운팅하는 기능을 추가하여 구현한 클래스
- ConnectionMaker를 멤버변수로 가지고 counter 기능을 추가함
- 위와 같이 부가기능을 추가하기도 간편하다
4 용어 정리
빈
- 스프링이 IoC 방식으로 관리하는 오브젝트
- 관리되는 오브젝트(managed object)
- 스프링이 직접 생성과 제어를 담당하는 오브젝트만을 빈이라 부른다
빈 팩토리
- 스프링의 IoC를 담당하는 핵심 컨테이너
- 빈을 등록하고, 생성하고, 조회하고, 반환한다.
애플리케이션 컨텍스트
- 빈 팩터리를 확장한 IoC 컨테이너
- 빈 팩터리에 각종 부가 서비스를 추가로 제공한다
- 스프링이 제공하는 애플리케이션 지원 기능을 모두 포함해서 이야기할 때 이 용어를 쓴다
설정 메타정보
- IoC를 적용하기 위해 사용하는 메타정보
- XML, 어노테이션 등
IoC 컨테이너
- IoC 방식으로 빈을 관리하는 무언가를 말할 때 이 용어를 사용한다
- 스프링 컨테이너, 컨테이너라고도 부른다.
스프링 프레임워크
- IoC 컨테이너, 애플리케이션 컨텍스트를 포함해서
- 스프링이 제공하는 모든 기능을 통틀어 말할 때 이 용어를 주로 사용한다