IOC(Inversion of Control)란?
IOC란 "제어의 역전" 이라는 의미로, 메소드나 객체의 호출작업을 개발자가 결정하는 것이 아니라, 외부(IOC 컨테이너)에서 결정되는 것을 의미한다.
즉, 객체의 의존성을 역전시켜 객체 간의 결합도를 줄이고 유연한 코드를 작성할 수 있게 하여 가독성 및 코드 유지보수를 편리하게 할 수 있게 한다.
스프링 컨테이너에서는 오브젝트(빈)의 생성과 의존 관계 설정, 사용, 제거 등의 작업을 애플리케이션 코드 대신 스프링 컨테이너가 담당한다.
스프링 컨테이너가 코드 대신 오브젝트에 대한 제어권을 갖고 있다고 해서 IoC라고 부른다.
스프링 컨테이너 = IOC 컨테이너
Repository 객체가 있을때 과거에는 아래와 같이 개발자가 직접 제어했다.
하지만 현재 제어권은 컨테이너로 넘어갔고 객체의 생성과 생명주기의 관리까지 할 수 있기 때문에 아래와 같은 방식으로 바뀐다.
IOC 컨테이너란?
스프링에서 IoC를 담당하는 컨테이너를 빈 팩토리, DI 컨테이너, 애플리케이션 컨텍스트라고 부른다.
스프링 컨테이너는 단순한 DI 작업보다 더 많은 일을 하는데, DI를 위한 빈 팩토리에 여러 가지 기능을 추가한 것을 어플리케이션 컨텍스트라고 한다. 그 자체로 IoC와 DI 그 이상의 기능을 가졌다고 보면 된다.
애플리케이션 컨텍스트 기능
1. 메시지 소스를 활용한 국제화 기능: 한국어, 영어 처리 가능
2. 환경 변수: 로컬, 개발, 운영 등을 구분해서 처리
3. 애플리케이션 이벤트: 이벤트를 발행하고 구독하는 모델을 편리하게 지원
4. 편리한 리소스 조회: 파일, 클래스 패스, 외부 등에서 리소스를 편리하게 조회
의존성 주입(DI)이란?
DI(Dependency Injection)란 Spring 프레임워크의 3가지 핵심 프로그래밍 모델중 하나로, 객체를 직접 생성하는게 아니라 외부에서 생성한 후 주입 시켜주는 방식입니다. 외부에서 두 객체간의 관계를 결정해주는 디자인패턴으로 인터페이스를 사이에 두고 클래스 레벨에서는 의존관계과 고정되지 않도록 하고 런터임시에 관계를 동적으로 주입하여 결합도를 낮출수 있게 하는 기법이다.
DI(Dependency Injection) 특징
의존성 주입은 IoC(Inversion of Control, 의존성 역전) 원칙하에 객체간의 결함을 약하게 해주고 유지보수가 좋은 코드를 만들어 준다.
DI 컨테이너를 통해 서로 강하게 결합되어있는 두 클래스를 분리하고, 두 객체간 관계를 결정해줌으로써 결합도를 낮추고 유연성을 확보하고자 한다.
하나의 객체에서 다른 객체를 사용할 때 의존한다고 말하는데 의존의 방식에는 크게 방법이 세가지가 있습니다.
첫번째 방법은 New 생성자를 통해서 직접 생성하는 방법이고,
나머지 방법은 외부에서 생성된 객체를 setter()와 생성자를 통해 사용하는 방법이다.
A 객체에서 B, C객체를 사용(의존)할 때 A객체에서 직접 생성하는 것이 아니라 외부(IOC컨테이너)에서 생성된 B, C객체를 조립(주입)시켜 setter 혹은 생성자를 통해 사용하는 방식이다.
만약, A객체에서 의존대상인 B객체를 New 생성자를 통해 직접 생성했을 때, B객체가 변하면 A에도 영향을 미쳐서 수정하기 번거로워진다. B객체에 기능이 추가되거나 변경되면 A객체도 영향을 준다는말이다. 즉, 직접 생성하는 방법보다는 외부에서 생성된 객체를 setter() 또는 생성자를 통해 주입시키는 방법이 관리에 더 유용하다.
setter 주입 방식은 주입 받는 객체가 변경 가능성이 있을 경우 사용한다.
하지만 주입할 대상이 없을 경우 오류가 발생하는 단점이있다.
생성자 주입 방식은 생성자의 호출 시점에 1회 호출 되는 것이 보장된다. 따라서 객체가 변하지 않거나, 반드시 객체의 주입이 필요한 경우에 강제하기 위해 사용할 수 있다.
생성자 주입의 장점
1. 객체의 불변성 확보
수정의 가능성이 있다는건 유지보수성을 떨어뜨린다. 따라서, 변경의 가능성을 배제하고 불변성을 보장하는 것이 좋다.
2. 테스트 코드의 작성 용이
생성자 주입만 순수 자바로 테스트를 작성할 수 있게 해준다.
3. final 키워드 작성 및 Lombok과의 결합
생성자 주입을 사용하면 필드 객체에 final 키워드를 사용할 수 있으며, 컴파일 시점에 누락된 의존성을 확인할 수 있다.
4. 순환 참조 에러 방지
생성자 주입을 사용하면 애플리케이션 구동 시점(객체의 생성 시점)에 순환 참조 에러를 예방할 수 있다.
스프링에서 객체의 생성과 소멸에 관련된 작업을 자동적으로 수행해주는데, 객체가 생성되는 곳을 스프링에서는 Bean 컨테이너라고 한다.
스프링에서는 객체를 Bean이라고 부르며, 프로젝트가 실행될 때 사용자가 Bean으로 관리하는 객체를 모두 자동으로 생성해준다.
'BackEnd > Spring' 카테고리의 다른 글
[Spring] AOP란? (0) | 2022.07.28 |
---|---|
[Spring] POJO란? (0) | 2022.06.19 |
[Spring] DAO, DTO, VO란? (0) | 2022.06.10 |
[Spring] 스프링(Spring)이란? (0) | 2022.06.09 |