본문 바로가기

PROGRAMMING/SPRING

[개념] IOC, DI 그리고 Container

IOC(Inversion Of Control)

기존의 개발자가 구현 객체를 스스로 생성하고 연결하고 실행했다면,

말 그대로 제어권을 역전시켜 이러한 부분을 프레임워크나 컨테이너에서 대신해주는 것을 말한다.

 

IOC 도입의 이유?

기존 방법은 개발자가 직접 제어하는 방식으로 구현체 간의 결합도가 높아 유지보수성이 떨어진다.

IOC는 인터페이스로 설계하여 실행시점에 실제로 어떤 구현체가 들어갈지는 컨테이너가 제어하는 방식이다. 

 

DI와 DL은 IOC를 구현하는 방법이며 포함된 개념이라고 볼 수 있다.

 

 

DL(Dependency Loopup)

직역하면 의존성 검색으로

Container에 등록된 빈을 검색해오는 것을 말한다.

 

DI(Dependency Injection)

직역하면 의존성 주입으로

클래스간 의존관계를 컨테이너가 주체가 되어 생성하는 것을 말한다.

의존성 주입은 3가지 방법이 있는데

 

1. Field Injection 

   변수 선언부에 @Autowired 어노테이션을 붙여 의존성 주입하는 방법이다.

   코드가 간결하다는 장점은 있지만,

   DI 프레임워크 없이는 구현체를 인젝트하거나 접근할 수 없어 순수 자바 테스트 케이스를 생성하기 힘들다.

   결국 setter가 또 필요해지는데 그럴바엔 2번 방법을 사용하는 게 낫다.

 

2. Setter Injection

   @Autowired를 변수가 아니라 변수의 set method에 생성

   하지만 해당 set method를 통해 DI가 이뤄지지 않더라도 호출이 가능한데 이경우 NullPointExcpetion이 발생한다.

   이 부분을 보완할 수 있는 방법이 3번 생성자 주입이다.

 

3. Constructor Injection

   생성자에서 의존성 주입을 하는 방법으로 가장 추천되는 방법이다.

   Spring 4.3 버전부터는 단일생성자에 한해 @Autowired 도 생략 가능하다.

   장점으로는 생성자 호출 시점에 딱 1번만 호출되기 때문에 생성 이후 변경이 불가능하여 불변이 보장된다.

   Interface를 final로 선언해 롬복의 @RequiredArgsConstructor를 활용하면 가장 깔끔하다.