IoC(Inversion of Control)
용어 그대로 코드의 로직이 일반적인 제어의 흐름이 아니라 역전된 것을 말한다. 일반적인 경우에는 메서드나 객체의 호출 작업을 개발자가 결정하였다. 예를 들어서 하나의 객체가 다른 객체를 사용하기 위해서 new로 객체를 생성하는 코드를 개발자가 직접 작성하는 경우들이라 보면 된다. 하지만 이것은 IoC에서 역된된다. new를 사용하지 않고 외부( like 스프링 )에서 객체를 생성하고 필요에 따라 넣어주는 방식으로 일반적인 제어의 흐름이 역전되버린다.
이러한 제어의 역전의 장점으로는 객체간 결합도를 낮춰주며 코드의 변경이나 추가가 용이한 유연한 코드를 작성할 수 있도록 한다.
DI(Dependency Injection)
스프링에서는 의존 관계 주입기능을 제공한다. 이것이 다른 프레임 워크와 차별화되는 특징 중 하나다. 간단하게 말하면 의존성 주입이라는 말은 사용하는 쪽에서 객체를 직접 생성해서 쓰는게 아니라 외부에서 생성해서 받아서 쓴다고 말하면 될 것이다. 이러한 DI라는 말은 디자인 패턴에서 나왔으며 두 객체간의 연관관계가 있는 경우 이것이 고정되는 것이 아니라 그 사이에 인터페이스를 두어서 필요에 따라 동적으로 관계를 주입하여 유연성을 확보하고 결합도를 낮추자는 철학에서 나온다.
방법 1은 A 객체에서 B와 C를 직접 생성하는 방식을 사용하고 방법 2는 외부에서 생성된 객체를 setter() or 생성자를 통해 주입하는 방법을 사용한다. 방법1의 같은 경우에는 강한결합이 만들어져 유지보수가 어려워 진다. 이러한 강한 결합을 방법2의 방식으로 느슨한 결합으로 풀어내게 된다. 이 과정에서 다형성의 원리를 사용하여 기존 객체를 인터페이스를 구현하도록 변경하고 그 인터페이스를 매개변수로 받는 방식을 사용한다.
방법1의 코드를 다음과 같이 정의하였다.
public class Store {
private Apple apple;
public Store() {
this.apple = new Apple();
}
}
방법2의 코드는 매개변수를 interface로 받아서 기존에 Store 객체와 Apple 객체의 결합도를 느슨하게 하고 대신 Interface와 결합하여 새로운 과일이 추가되는 경우에도 코드 유지보수가 용이하게 만든다. 이와 같은 경우 객체의 생성은 외부에서 일어나고 필요한 경우에 Fruit을 구현하는 새로운 과일 객체를 더 구현해도 된다. 이 때문에 Store 객체는 더이상 과일 객체 생성과 변경에 관여하지 않아도 된다. ( 암튼 매우 유연해진다는 말임.. )
public interface Fruit {}
public class Apple implements Fruit {}
public class Store{
private Fruit fruit;
public Store(Fruit fruit){
this.fruit = fruit;
}
}
사실상 DI나 IoC나 비슷한 말이다. 스프링은 이러한 아이디어에 착한하여 프레임워크가 설계되었다. IoC 컨테이너 (혹은 DI 컨테이너)는 Bean이라는 것을 생성하고 관리한다. (이 Bean은 스프링에서의 객체를 의미한다. ) 이 컨테이너에는 굉장히 많은 Bean들이 있을 수 있으며, 이러한 Bean은 개발자가 필요한 경우 주입하여 사용한다. 즉 어떤 객체나 코드 영역에서 주입으로 인한 참조관계가 형성된다는 것이다. 그리고 개발자는 new 키워드를 사용한적 없이 단순히 외부에서 생성된 객체를 사용하는 것 뿐이다.
하지만 이렇게 외부에서 객체를 생성하는데 객체를 계속 생성하고 소멸하면 아무리 GC가 성능이 좋다고 하더라고 부담이 될 수 있다. 이때 객체의 생성에는 인스턴스를 오직 하나만 생성하는 방식인 싱글턴 패턴이 적용될 수 있다.( 물론 설정에 따라 변경은 가능 )
'스프링(부트아님ㅋ)' 카테고리의 다른 글
DispatcherServlet 정리 (0) | 2023.07.16 |
---|---|
Spring 애너테이션 몇 가지 정리 (0) | 2023.05.14 |
스프링 MVC 5.0.7에서 모바일 화면 적용하기 (0) | 2023.05.02 |