Spring

스프링IoC 컨테이너 (Feat. 빈(Bean), 빈 스코프(Bean Scope))

Lea Hwang 2022. 10. 24. 16:42

스프링 IoC컨테이너의 IoC는 Inversion of Control으로 의존 관계 주입(Dependency Injection, DI)라고 

하며 어떤 객체(예제에서는 StudioService)가 사용하는 의존 객체(StudioRepository)를 직접 만들어 사용하는 게 아니라 주입받아 사용하는 방법을 말합니다.

@Service
@RequiredArgsConstructor
public class StudioService {

    private final StudioRepository studioRepository;
    
    ...
}

 

이 한 줄을 읽으면서 혹시 이해가 안 가는 부분이 있으셨나요? 바로 저...

어떤 부분 때문에 이해가 안 가셨나요? 저의 경우는 각각의 개념에 대한 이해뿐만 아니라 개념들이 서로 어떻게 연결되는지 몰라서였습니다. 

혹시나 저와 같은 분들이 있으실까해서 여러 포스팅에 걸쳐 제가 공부한 내용을 바탕으로 개념의 정의나 개념들이 어떤 식으로 연결되는지 적어보려 합니다.

 

 

 

 

IoC란

  • IoC란 Inversion of Control의 줄임말이며, 제어의 역전이라고 합니다.
  • 객체의 생성에서부터 생명주기의 관리까지 모든 객체에 대한 제어권을 개발자가 아닌  IoC 컨테이너가 가지고 있다고 해서 제어의 역전이라고 부릅니다.
  • 스프링 컨테이너를 IoC 컨테이너라고도 합니다.

 

간단하게 개념 check!

👌 컨테이너
컨테이너는 보통 인스턴스의 생명주기를 관리하며, 생성된 인스턴스들에게 추가적인 기능을 제공하도록 합니다.

👌 빈
Spring IoC 컨테이너가 관리하는 자바 객체를 빈(Bean)이라고 부릅니다.
빈들을 컨테이너로부터 가져와서 사용할 수 있습니다.

👌 컨테이너와 빈 설계
스프링 초기 XML로 설계했지만 지금은 어노테이션 기반의 DI를 지원하기 시작했으며
오늘날에는 빈으로 등록하고 , 빈으로 등록되어있는 객체를 주입받아서 사용할 수 있습니다.

 

 

Spring 컨테이너

  • 인스턴스의 생명주기를 관리하며, 생성된 인스턴스들에게 추가적인 기능을 제공하도록 합니다.
  • 객체의 생성과 소멸을 컨트롤합니다.
  • BeanFactory , ApplicationContext 두 종류가 있습니다.
    • BeanFactory 
      • 스프링 IoC컨테이너의 최상위 인터페이스이고 가장 중요한 메서드는 getBean()입니다.
      • 빈을 등록하고 생성하고 조회하고 돌려주고, 그 외에 부가적인 빈을 관리하는 기능을 담당합니다.
      • 빈 팩토리가 빈의 정의는 즉시 로딩하는 반면, 요청이 있기까지 인스턴스화를 하지 않습니다.
      • getBean()이 호출돼야, 의존성 주입을 이용해 빈을 인스턴스 화하고 빈의 생명주기가 시작됩니다.
      • 실질적으로 자주 사용하는 BeanFactory는  ApplicationContext 인터페이스입니다.
    • ApplicationContext 
      • BeanFactory를 상속, 확장한 향상된 컨테이너
      • 컨텍스트 초기화 시점에 모든 싱글톤 빈을 미리 생성하므로, 인스턴스를 즉시 사용하게 보장합니다.
      • 기본적인 기능은 빈 팩토리와 동일하고 스프링이 제공하는 각종 부가 서비스를 추가로 제공합니다.
        • 국제화가 지원되는 텍스트 메시지 관리
        • 이미지 같은 파일 자원을 로드할 수 있는 포괄적인 방법을 제공
        • 리너스로 등록된 빈에게 이벤트 발생을 알려줌
      • Spring Bean 어노테이션을 명시해주면, ApplicationContext라는 컨테이너를 사용한 것이고
        애플리케이션의 실행과 동시에 @Bean이 명시된 객체를 생성하여 관리해줍니다.
간단하게 정리해보자면,

- ApplicationContext는 BeanFactory의 기능을 상속받아 빈 관리 기능 + 편리한 부가 기능을 제공합니다.
- BeanFactory를 직접 사용할 일은 거의 없고 부가기능이 포함된 ApplicationContext를 사용합니다.
- BeanFactory나 ApplicationContext를 스프링 컨테이너라 합니다.

 

 

스프링 IoC컨테이너가 관리하는 객체가 Bean인지 아닌지 확인해야 하는 이유

이에 대한 답을 바로 알아보기 전에, Bean으로 등록 시 장점부터 알아보자면

(빈은 스프링 IoC 컨테이너가 관리하는 객체로) 크게 3가지 장점이 있습니다.

  • 의존성 관리
  • 스코프
    • 싱글톤 : 하나만 만들어서 사용하는 것
      • 별다른 설정 없을 시 싱글톤, 메모리 효율적, 런타임 성능 최적화에도 유리
    • 프로토타입 : 매번 다른 객체를 사용하는 것
  • 라이프사이클 인터페이스 지원(예 @PostConstruct)
    •  스프링 IoC 컨테이너에 등록된 빈 들에 국한해서, 어떤 빈이 만들어졌을 때 추가적인 작업을 하고 싶을 때

의존성 가진 단위 테스트를 만들기 힘들다는 단점이 있지만.
  @Mock 이용해서 가짜 객체를 만들어 의존성 주입할 수 있습니다.

 

 

 

즉, 스프링 IoC컨테이너가 관리하는 객체가 Bean인지 아닌지 확인해야 하는 이유는

1. 의존성 주입을 받으려면 빈이 되어야 합니다.

2. 빈의 스코프 때문입니다.

 

💡 그럼 빈의 스코프(Bean Scope)란 무엇일까요?
스코프(Scope)는 영어 뜻 그대로 범위인데 여기서는 빈이 관리되는 범위를 뜻합니다.
Spring의 Bean은 별다른 설정이 없으면 Singleton Scope로 생성됩니다. 싱글톤 스코프는  Spring 프레임워크에서 기본이 되는 스코프로 스프링 컨테이너의 시작과 종료까지 1개의 객체로 유지되는 특징을 가지고 있습니다. 

Scope의 종류를 살펴보자면, 
1. 싱글톤
  Spring 프레임워크에서 기본이 되는 스코프
  스프링 컨테이너의 시작과 종료까지 1개의 객체로 유지됨

2. 프로토타입
  빈의 생성과 의존관계 주입까지만 관여하고 더는 관리하지 않는 스코프
  요청이 오면 항상 새로운 인스턴스를 생성하여 반환하고 이후에 관리하지 않음
  프로토타입을 받은 클라이언트가 객체를 관리해야 함

3. 웹
  request: 각각의 요청이 들어오고 나갈 때까지 유지되는 스코프
  session: 세션이 생성되고 종료될 때까지 유지되는 스코프
  application: 웹의 서블릿 컨텍스트와 같은 범위로 유지되는 스코프 

 

 

 

 

정리를 해보자면, 

애플리케이션  전반적으로 인스턴스(StdioService)는 오직 하나만 사용해도 됩니다.  

이렇게 싱글톤으로 객체를 만들어 관리하고 싶을 때에도 IoC컨테이너를 사용하면 편리한데요.

 IoC컨테이너에 등록된 빈들은 기본적으로 싱글톤 스코프로 빈이 등록됩니다.

 

애플리케이션 전반에서 IoC컨테이너로부터 DI 받아서 사용한다면 그것은 항상 같은 객체 일 것이므로

매번 만들어 사용하는 프로토 타입에 비해 메모리 면에서 효율적이고 런타임 시 성능 최적화 유리하고

애플리케이션 컨텍스트가 싱글톤으로 빈을 관리하면 대규모 트래픽을 처리할 수 있는 장점도 있습니다.

 

 

 

 

 


 

 

 

 

참고:

https://steady-coding.tistory.com/600

https://velog.io/@jakeseo_me/%ED%86%A0%EB%B9%84%EC%9D%98-%EC%8A%A4%ED%94%84%EB%A7%81-%EC%A0%95%EB%A6%AC-%ED%94%84%EB%A1%9C%EC%A0%9D%ED%8A%B8-1.5-%EC%8A%A4%ED%94%84%EB%A7%81%EC%9D%98-IoC

https://bangu4.tistory.com/285?category=1046984

https://www.youtube.com/watch?v=L-0UvbFUXrk

https://100100e.tistory.com/285