빈 생명주기 콜백

  • 스프링 빈은 객체를 생성하고 의존관계 주입이 다 끝난 다음 초기화 작업을 할 수 있는 준비가 된다.
  • 스프링은 의존관계 주입이 완료되면 스프링 빈에게 콜백 메서드를 통해 초기화 시점을 알려주는 기능을 제공한다.
  • 또한 스프링 컨테이너가 종료되기 직전에 소멸 콜백을 주어 안전하게 종료 작업을 할 수 있게 지원한다.

 

스프링이 지원하는 빈 생명주기 콜백 방법

 

1. 인터페이스

  • InitializingBean, DisposableBean
  • 스프링 초창기에 주로 사용하던 방법
  • 스프링 인터페이스에 의존적, 외부 라이브러리 적용 불가 등의 단점

 

2. 설정 정보

  • @Bean(initMethod = "init", destroyMethod = "close")
  • 메서드 이름 자유롭게 사용, 설정 정보를 사용하기 때문에 코드를 고칠 수 없는 외부 라이브러리에도 적용 가능
  • destroyMehtod의 경우 따로 적지 않아도 close, shutdown 이라는 메서드 이름을 추론해서 호출

 

3. 애노테이션

  • @PostConstruct, @PreDestroy
  • 자바 표준 기술로 가장 권장하는 방법
  • 유일한 단점으로는 외부 라이브러리에 적용 못하기 때문에 이 경우는 @Bean 설정 정보 사용

 

 

빈 스코프

  • 생성된 빈이 존재할 수 있는 범위
  • 일반적으로 스프링 빈은 싱글톤 스코프로 생성
  • @Scope

 

스프링이 지원하는 스코프

  • 싱글톤 : 스프링 컨테이너의 시작과 종료까지 유지되는 가장 넓은 범위의 기본 스코프
  • 프로토 타입 : 스프링 컨테이너가 의존관계 주입, 초기화까지만 관여하고 더는 관리하지 않는 매우 짧은 범위의 스코프
  • 웹 스코프 : request, session, application 등 특정 웹 요청까지 유지되는 스코프

 

프로토타입 빈

 

1. 특징

  • 스프링 컨테이너 생성 시점에 초기화가 되는 싱글톤 빈과 달리, 프로토타입 빈은 스프링 컨테이너에서 빈은 조회할 때 생성
  • 조회를 할 때마다 새로운 스프링 빈이 생성, 초기화
  • 프로토타입 빈을 조회한 클라이언트가 해당 빈을 관리

 

2. 문제점

  • 스프링 컨테이너 의존관계 주입 시점에 싱글톤 빈에 프로토타입 빈이 생성되어 주입
  • 이후 클라이언트가 프로토타입 빈의 메서드 요청 시 새로운 프로토타입 빈이 생성되는 것이 아니라 기존 빈 호출
  • 프로토타입 빈이 싱글톤 빈과 함께 계속 유지되는 문제 발생

 

3. 해결 방안

  • 의존관계 주입(D.I)이 아닌 의존관계 조회(Depengency Lookup)을 통해 필요시마다 프로토타입 빈을 새로 조회, 생성해야 한다.
  • 스프링이 제공하는 ObjectProvider (기존 ObjectFactory + 편의 기능 추가)
  • 지정한 빈을 컨테이너에서 대신 찾아주는 D.L 기능 제공
  • getObject() 메서드를 통해 항상 새로운 프로토타입 빈이 생성
  • 스프링에 의존적이지만 기능이 단순해서 단위테스트, mock 테스트 만들기 편리
  • 싱글톤 스코프 빈을 거의 사용하기 때문에 직접적으로 프로토타입 빈을 사용할 경우는 적음 

 

 

스코프와 프록시

 

  • @Scope(proxyMode = ScopedProxyMode.TARGET_CLASS)
  • 스프링 컨테이너가 CGLIB (바이트코드를 조작하는 라이브러리)를 사용해서 가짜 프록시 객체를 생성
  • 실제 객체를 상속받은 프록시 객체를 스프링 빈으로 등록, 싱글톤 빈처럼 사용
  • 싱글톤을 사용하는 것 같지만 실제로는 다르게 동작하므로 주의해서 사용
  • 프록시 객체는 요청이 올 경우 그 때 내부에서 실제 빈을 요청하는 위임 로직이 들어있다.
  • ObjectProvider를 사용하든, Proxy를 사용하든 핵심은 실제 객체 조회를 필요한 시점까지 지연 처리 한다는 점

 

 

 

참고(https://www.inflearn.com/users/@yh)

+ Recent posts