[스프링 숲] IoC 컨테이너

byeol·2023년 4월 15일
0

스프링 강의를 듣고 있지만 전체적인 숲을 모른채
이론에 집중하고 있는거 같아
최주호님의 스프링부트 개념정리 강의를 들으며 스프링에 대해서 더 자세히 알아보려고 합니다.
강의의 내용을 그대로 정리하기 보다는 가졌던 의문점(✅)들을 중심으로 정리하겠습니다.

IoC 컨테이너를 가진다.

class : 설계도
Object : 실체화가 가능한 것
Instance : 실체화가 된 것!

Java에서는 class에 의해서 Object를 설계합니다.
이 Object는 실체화가 가능하고 new라는 키워드를 통해 Instance로 실제 세계로 나오게 됩니다.

위 메모리 구조를 살펴보면
크게 method 영역과 heap영역 그리고 stack 영역이 존재합니다.
heap 영역에는 new 키워드로 생성된 객체와 배열(참조변수가 저장되는 것이 아닙니다. 참조변수가 가리키는 객체가 저장됩니다!)이 저장됩니다.

✅ 만약에 두 개의 메소드 사이에서 하나의 객체를 공유하고자 한다면
어떻게 해야할까요?
위 구조와 같다면 서로 다른 두 객체는 독립적으로 heap 영역에 올라가게 됩니다.
여기서 IoC 컨테이너를 이용한다면 하나의 객체만 메모리에 올라가게 할 수 있으며
모든 메소드에서 공유가 가능합니다.

✅ 그렇다면 IoC와 static의 차이가 무엇인지 의문점이 생겼습니다.

method가 static이 아니라면 new 사용해서 새로 만든 후에
Class의 method를 호출합니다.
여기서 스프링의 IoC 개념이 무너집니다.
스프링은 객체를 new로 만들지 않습니다.
왜냐하면 객체의 생성 및 소멸에 대한 권한을 컨테이너에 넘겼기 때문입니다.
만약에 static을 사용하려면 의존되는 객체를 static 또는 new로 만들어야 합니다.
그러면 굳이 스프링을 사용할 필요가 없습니다.
스프링의 핵심 기능인 IoC를 사용하지 않는 것과 같습니다.
static으로 만들면 heap이 아닌 class 영역에 상주시켜 속도나 메모리 면에서 더 빠를 수 있습니다.
하지만 static method 안에 다른 객체를 new생성한다거나 해당 method가 호출될 때마다
객체가 새로 생성되며 그 객체 대한 생성과 소멸을 직접 관리해야 합니다.

스프링은 이런 객체 대한 생성과 소멸을 관리해주며,
싱글톤 레지스트리라는 방법을 사용하여
객체를 싱클톤과 같이 한번만 생성하기 때문에
오히려 성능이 좋을 수 있습니다.
출처 : https://okky.kr/questions/291799

정리하면 종속성을 더 나은 방법으로 제공하는 것 (개발자가 편하도록) + 성능

✅ 그렇다면 IoC 컨테이너는 어떤 메모리 영역에 올라갈까요?

출처: https://www.inflearn.com/questions/205449/ioc-%EC%BB%A8%ED%85%8C%EC%9D%B4%EB%84%88-%EC%A7%88%EB%AC%B8%EC%9E%85%EB%8B%88%EB%8B%A4

✅ 모든 자바 객체는 스프링 컨테이너에 등록될까요?
그렇지 않습니다. 스프링 컨테이너에 등록되는 자바 객체를 빈이라고 부릅니다.
생각해보면 모든 사용자에게 같은 객체를 사용하게 해야할 때와
각기 다른 객체를 사용하게 해야할 때가 있습니다.

모든 사용자가 같은 객체를 사용할 때, 자바 객체를 스프링 컨테이너에 등록하는데
이렇게 스프링 빈에 등록된 자바 객체를 빈이라고 부릅니다.

즉 모든 자바 객체는 스프링 빈에 등록되지 않고 그 중 일부만 스프링 컨테이너에 등록됩니다.

✅ 방법
@ComponentScan은 우리가 빈으로 등록하고자 하는 자바 객체를 찾아서 등록해줍니다.
우리가 등록하고자 하는 자바 객체는 클래스명 앞에서 @Component, @Service, @Contrller, @Respository가 붙습니다.

IoC에 등록된 객체를 모든 클래스에서 사용할 수 있는데
이렇게 불러와 사용하는 것을 DI(Dependency Injection)라고 합니다.

✅ DI의 과정
IoC에 저장된 객체를 가져올 때

A a = new A();

위와 같이 new를 통해 가져오는 것이 아닙니다.
위와 같이 가져온다면 결국 IoC를 이용하는 것이 아니라
새로운 A라는 객체를 heap 메모리 영역에 로드하는 것입니다.

따라서 아래와 같이 가져오기로 합니다.

@Autowirted
A a ;

@Autowirted라는 어노테이션을 이용합니다.
이 @Autowirted라는 어노테이션은 IoC에 등록된 빈들을 스캔해서 똑같은 클래스 유형을 가진
객체를 주입해주는 역할을 가집니다.

여기서 의존성 주입이 일어납니다.

✅ 그렇다면 어노테이션이란 무엇일까요?
주석은 글이며 컴파일러가 무시합니다.
하지만 어노테이션은 주석이면서 컴파일러가 무시하지 않는 힌트를 제공합니다.

스프링에서는 어노테이션을 이용해서 주로 객체를 생성합니다.
@Component, @Service, @Repository가 여기에 해당됩니다.

또한 앞에서 배운 @Autowirted는 로딩된 객체를 해당 변수에 집어 넣습니다.

profile
꾸준하게 Ready, Set, Go!

0개의 댓글