BackEnd Developer, Love Crossfit, Welcome to Jay's blog

빈 라이프 사이클과 Scope

|

Index

  • 빈 라이프 사이클
    • 컨테이너 초기화와 종료
    • 빈 객체의 라이프 사이클 - 초기화 / 소멸 메소드
  • 빈 객체의 생성과 관리 범위
    • 스프링 빈의 스코프
    • Singleton 패턴과 Singleton Registry
  • References

빈 라이프 사이클

컨테이너 초기화와 종료

스프링 컨테이너는 초기화와 종료라는 라이프 사이클을 갖는다.

컨테이너 초기화는 컨텍스트 객체 생성시 이루어지고 초기화된 컨테이너는 설정 클래스 정보를 읽어와 알맞은 빈 객체를 생성해 빈을 연결(의존 주입)하는 작업을 수행한다.

컨테이너 초기화가 완료되면 컨테이너를 사용해서 빈 객체를 가져 올 수 있다.

정리해서 컨테이너를 초기화하고 종료할 때 다음 작업이 같이 수행된다.

  • 컨테이너 초기화 -> 빈 객체의 생성, 의존 주입, 초기화
  • 컨테이너 종료 -> 빈 객체의 소멸

이렇게 스프링 컨테이너의 라이프 사이클에 따라 빈 객체도 생성과 소멸이라는 라이프 사이클을 갖게 된다.

스프링 빈 객체의 라이프 사이클

스프링 컨테이너를 초기화 할때 컨테이너는 컴포넌트 스캔과 설정 클래스에서 정보를 읽어와 빈으로 등록하고(빈 객체 생성) 빈 간의 의존 관계를 연결한다. 의존 설정이 끝나면 빈 객체의 지정된 메소드를 호출해 빈 객체를 초기화하고, 스프링 컨테이너 종료시에는 지정된 소멸 메소드를 호출하여 빈 객체의 소멸을 처리한다.

여기서 지정된 메소드란 1)스프링에서 제공하는 인터페이스를 상속받아 구현한 메소드와 2)설정 클래스에서 메소드를 직접 지정해 커스텀 메소드를 사용하는 방법이 있다.

1.스프링에서 제공하는 인터페이스를 알맞게 구현

  • org.springframework.beans.factory.InitializingBean
  • org.springframework.beans.factory.DisposableBean
public interface InitializingBean {
    void afterPropertiesSet() throws Exception;
}

public interface DisposableBean {
    void destroy() throws Exception;
}

2.커스텀 메소드를 대신 사용 - @Bean 속성 사용해 사용할 메소드 지정 or 설정 메소드에서 직접 초기화 수행

@Bean(initMethod = “connect”, destroyMethod = “close”)

그 결과 스프링 컨테이너는 초기화 과정에서는 빈 객체의 지정된 초기화 메소드를 실행하고, 소멸 과정에서는 빈 객체의 소멸 메소드를 실행하게 된다.

초기화와 소멸 과정이 필요한 예가 데이터베이스 커넥션 풀이다. 커넥션 풀을 위한 빈 객체는 초기화 과정에서 데이터베이스 연결을 생성한다. 컨테이너를 사용하는 동안 연결을 유지하고 빈 객체를 소멸할 때 사용중인 db 연결을 끊어야 한다.

또 다른 예로 채팅 클라이언트가 있다. 채팅 클라이언트는 시작할 때 서버와의 연결을 생성하고, 종료할 때 연결을 끊는다. 이때 서버와의 연결을 생성하고 끊는 작업을 초기화 시점과 소멸 시점에 수행하면 된다.

빈 객체의 생성과 관리 범위

스프링 컨테이너는 컨테이너 하나당 빈 객체를 한 개만 생성해서 공유한다. 이 때 빈은 싱글톤 범위를 갖는다. 범위를 다르게 지정하고 싶다면 @Scope 애노테이션을 사용하면 된다. 빈 객체를 생성할 때 마다 매번 새로운 객체를 사용하고 싶다면 프로토타입을 사용하면 된다.

@Bean
@Scope(“prototype”)

prototype은 객체 하나 하나의 상태를 기억해야하는 상황(stateful)에서 주로 사용되며, 데이터 접근을 도와주기만 하면 되는 객체인 DAO처럼 stateless한 상황(상태를 기억할 필요가 없는 상황)에서는 singleton이 사용된다.

이때, 프로토타입에서 주의할 점은 컨테이너 종료시 빈 객체의 소멸 메소드를 실행하지 않는다는 것이다. 때문에 빈 객체의 소멸 처리를 코드에서 직접해야 한다.

스프링 빈의 스코프

스프링이 관리하는 객체인 빈이 생성되고, 존재하고, 적용되는 범위를 빈의 스코프(scope)라 한다.

  • 스프링 빈의 기본 스코프는 싱글톤 스콥이다. (컨테이너 당 한 개의 오브젝트만 만들어 공유, stateless, 읽기전용)
  • 그외 스코프
    • 컨테이너에 빈을 요청할 때마다 새로운 오브젝트를 만들어주는 프로토타입 스코프(prototype)
    • 웹을 통해 새로운 HTTP 요청이 생길 때마다 생성되는 요청 스코프(request)
    • 웹 세션과 스코프가 유사한 세션 스코프(session)

Singleton 패턴과 Singleton Registry

자바의 싱글톤 패턴 구현은 여러 단점이 있기 때문에 싱글톤 패턴을 대신해서 스프링이 직접 싱글톤 형태의 오브젝트를 만들고 관리하는 기능을 제공한다. 이를 싱글톤 레지스트리(singleton registry)라 한다.

싱글톤 레지스트리의 장점은 static 메소드와 private 생성자를 사용해야하는 - private 생성자는 외부에서 호출할 수 없기 때문에 의존 주입이 어렵고, 다른 생성자가 없다면 상속이 불가능하므로 다형성을 적용할 수가 없다 - 클래스가 아니라 일반 자바 클래스를 싱글톤으로 활용하게 해준다는 점이다. 싱글톤 레지스트리 덕분에 싱글톤 방식으로 사용될 애플리케이션 클래스가 public 생성자를 가질 수 있게 되어 생성자를 통해 사용할 오브젝트 주입이 가능해졌다. 또한 테스트 환경에서는 자유롭게 오브젝트를 만들고, 테스트를 위한 mock 오브젝트로 대체하는 것도 간단해졌다.

싱글톤 패턴: 단 한개의 오브젝트만 만들어 사용한다

싱글톤 레지스트리: 싱글톤 패턴 구현을 대신해 스프링이 직접 싱글톤 형태의 오브젝트를 만들고 관리한다

References

토비의 스프링 3.1
초보 웹 개발자를 위한 스프링5 프로그래밍 입문