본문 바로가기
Spring & Boot

[Spring] D.I (Dependency Injection) 의존성 주입, 도대체 뭘까?

by 뜨는 해 2020. 9. 2.

 

(Dependency Injection) 의존성 주입?


스프링 프레임워크를 배우면서 중요한 것 중에 하나를 꼽으라고 한다면, 의존성 주입이 아닐까 싶다.

 

개인적으로 몰랐고, 정말 놀라운 사실은 의존성 주입이 예전에는 IOC(Inversion Of Control), 제어의 역행이라는 의미로 사용되었다는 것이다.

 

제어의 역행이 뭔지 간단하게 설명하자면,


객체들을 어떠한 외부의 존재로부터 관리받는, 어떻게 보면 말 그대로 객체의 관리를 외부에다가 맡기는

역행(Inversion)의 구조를 하고 있다는 것.


 

정확한 설명은 아니지만, 기본적으로 어떠한 객체를 외부로부터 관리 받는다고 생각한다.

 

예를 들면,

1
2
3
4
5
6
7
8
public class Fox {
 
    private final Fur fur;
 
    public Fox(Fur fur) {
        this.fur = fur;
    }
}
cs

여우는 북극 여우, 사막 여우, 붉은 여우 등등에 따라 털 색깔이 다르다, 그러면 Fox 클래스는 외부(즉, 부모)로부터 털 색깔을 물려받는다고 생각하면 쉽다.

 

스프링 프레임워크에서는 어떻게 의존성 주입을 할 수 있을까?

스프링 프레임워크는 코드 전체에 대한 제어를 맡는다. 즉, 주입 받아야 할 객체를 관리하고, 의존성 주입이 필요한 곳에 적재적소로 주입을 시켜준다. 이랑 연관된 것이 Spring Bean 일텐데 자세한 설명은 나중에 하겠다.

 

 

의존성 주입의 방법들


의존성 주입의 방법은 여러가지가 있는데, 나도 인터넷으로 알아보고, 확인해 본 결과 3가지 정도로 함축 되는 듯 싶다.

 


  1. 생성자를 이용한 주입 (Constructor Injection)
  2. Setter를 이용한 주입 (Setter Injection)
  3. @Autowired 어노테이션으로 주입

스프링 프레임워크를 만져보면서 느낀 점은, 보통은 생성자Setter 주입을 많이 쓴다는 것이다.

 

나는 개인적으로 생성자를 이용한 주입이 더 좋다고 생각한다.

Setter를 이용한 주입을 한다면 혹여나 나중에 어떤 일로 Setter 함수를 통한 DI가 바뀔 수 있다. 이런 실수를 미연에 방지하기 위해 나는 생성자 주입을 사용한다. 한 번 의존성 주입이 일어난 후, 더 이상 바꿀 수 없게 말이다.

 

 

 

싱글톤(Singleton)? 싱글톤이 뭐지...


싱글톤이 뭘까, 그 이전에 디자인 패턴(Design Pattern)에 대해서 알아야 한다.

디자인 패턴(Design Pattern), 나의 영원한 친구 나무위키에서 발췌한 내용을 간단히 살펴 보자면...


객체 지향 프로그래밍 설계를 할 때 자주 발생하는 문제들을 피하기 위해 사용되는 패턴.

...

 코드를 수정하거나 새로운 기능을 추가해야 하는데 의도치 않은 결과나 버그를 발생시키기 쉽고 성능을 최적화시키기도 어렵다.

...

디자인 패턴은 의사소통 수단의 일종으로서 이런 문제를 해결해준다.

 

 

종합해보자면, 객체 지향으로 인한 문제와 최적화를 사전에 해결 또는 개발자들끼리의 의사소통의 수단으로써 사용된다.

버그나 최적화의 문제를 미연에 방지하자는 목적으로 이해하고 있다.

 

그럼 스프링 프레임워크는 어떤 디자인 패턴을 가지고 운영을 할까? 디자인 패턴은 여러가지가 있고, 스프링은 그 중에서 싱글톤(Singleton)을 적용하고 있다.

 

그럼 싱글톤은 뭘까?



애플리케이션이 시작될 때 어떤 클래스가 최초 한번만 메모리를 할당하고,

그 메모리에 인스턴스를 만들어 사용하는 디자인패턴. 생성자가 여러 차례 호출되더라도 실제로 생성되는 객체는 하나이고 최초 생성 이후에 호출된 생성자는 최초의 생성자가 생성한 객체를 리턴한다. 

 

종합해보자면, 인스턴스는 같은 클래스로부터 여러 개 만들어질 수 있다. 하지만 싱글톤을 이용하게 되면

클래스로부터 생성된 인스턴스를 단 한개만 생성하고, 이용하는 것이다. 이것을 통한 장점이라면, 쓸데없는 메모리 낭비를 방지할 수 있다는 점?

1
2
3
4
5
6
7
8
9
10
public class Singleton {
 
    private static Singleton instance = new Singleton();
 
    private Singleton() {}
 
    public Singleton getInstance() {
        return instance;
    }
}
cs

 

코드를 보면, Singleton 클래스의 기본 생성자를 private로 설정했다. 생성자를 쓰지 못한다는 것은, 객체를 생성할 수 없다는 것. 그렇기에 싱글톤 클래스의 객체 한 개를 메모리 영역에 고정(static) 시켜놓고, 필요하다면 getInstance() 함수를 이용해 싱글톤 객체를 넘겨 준다. 결국 객체는 단 한개만 생성되는 것이다.

 

드디어 왔다, Spring Bean


스프링의 디자인 패턴은 싱글톤 패턴이라는 것을 배웠다. 그렇다면 어떻게 싱글톤 패턴을 지키고 있는 것일까?

스프링은 IoC 컨테이너라고 하는, 일종의 싱글톤 객체, 즉 Bean을 담고 관리한다.

Bean은 스프링의 XML 설정 파일을 토대로 객체를 생성하는데, 요즘은 어노테이션으로 처리하는 것 같다.

개인적으로 XML은 어렵고, 코드도 보기 지저분하기 때문에 사용하기 쉽지가 않다.

 

아무튼, 이렇게 생성된 객체는 스프링의 IoC 컨테이너에서 관리되고, 필요에 따라 의존성 주입을 시켜주게 된다.

 

어노테이션으로 IoC 컨테이너에서 관리하게 만드는 것이 있는데

 

@Bean

@Configuration

 

등이 있다.

'Spring & Boot' 카테고리의 다른 글

[Spring] REST API  (0) 2020.09.22
[Spring] @ResponseBody와 @RequestBody  (0) 2020.09.02
[Spring] MVC 패턴 - Model1, Model2  (0) 2020.09.02
[Spring] Spring Framework, 왜 쓸까?  (0) 2020.09.01