스프링

스프링 핵심 원리 기본 - 빈 생명주기 콜백

Rudtjs 2022. 7. 28. 12:48

빈 생명주기 콜백

애플리케이션 연결을 모두 종료하기 위해서는 객체의 초기화와 종료 작업이 필요하다. 스프링 빈은 객체를 생성하고 의존관계 주입이 끝난 다음에야 필요한 데이터를 사용할 수 있다. 따라서 초기화 작업은 의존관계 주입이 완료되고 난 다음 호출해야 한다.

 

스프링 컨테이너는 의존관계 주입이 완료되면 스프링 빈에게 콜백 메서드를 통해서 초기화 시점과 종료 시점을 알려준다.

콜백이란 어떤 이벤트가 발생했거나 특정 시점에 도달했을 때 시스템에서 호출하는 함수이다.

 

스프링 빈의 이벤트 라이프사이클

스프링 컨테이너 생성 ⇾ 스프링 빈 생성 ⇾ 의존관계 주입 ⇾ 초기화 콜백 ⇾ 사용 ⇾ 소멸전 콜백 ⇾ 스프링 종료

라이프 사이클을 보면 의존관계 주입후 초기화 콜백 메서드 호출을 하여 초기화 시점을 알려주고, 스프링 컨테이너 종료전에 소멸 콜백 메서드를 통해 소멸 시점을 알려준다.

 

  • 초기화 콜백: 빈이 생성되고, 빈의 의존관계 주입이 완료된 후 호출
  • 소멸전 콜백: 빈이 소멸되기 직전에 호출

 

빈 생명주기 콜백 3가지

  1. 인터페이스 
  2. 설정 정보에 초기화 메서드, 종료 메서드 지정
  3. @PostConstruct, @PreDestroy 어노테이션 지원

 

1. 인터페이스 (InitializingBean, DisposableBean)

  public class NetworkClient implements InitializingBean, DisposableBean {
    @Override
    public void afterPropertiesSet() throws Exception {
      connect();
      call("초기화 콜백");
    }

    @Override
    public void destroy() throws Exception {
      disConnect();
    }
  }
  • InitializingBean 은 afterPropertiesSet() 메서드로 초기화를 지원한다.
  • DisposableBean 은 destroy() 메서드로 소멸을 지원한다.

 

인터페이스 방식의 단점

  • InitializingBean, DisposableBean 인터페이스는 전용 인터페이스이다.
  • 오버라이드 하기 때문에 메서드 이름을 변경할 수 없다.
  • 코드를 고칠 수 없는 외부 라이브러리에 적용할 수 없다.

 

설정 정보에 초기화 메서드, 종료 메서드 지정

  public class NetworkClient {

    public void initCallback() {
      connect();
      call("초기화 콜백");
    }

    public void close() {
      System.out.println("NetworkClient.close");
      disConnect();
    }
  }

  @Configuration
  static class LifeCycleConfig {

    @Bean(initMethod = "initCallback", destroyMethod = "close")
    public NetworkClient networkClient() {
      NetworkClient networkClient = new NetworkClient();
      networkClient.setUrl("http://hello-spring.dev");
      return networkClient;
    }
  }
  • 메서드 이름을 커스텀 할 수 있다.
  • 스프링 빈이 스프링 코드에 의존하지 않는다.
  • 설정 정보를 사용하지 않기 때문에 커스텀할 수 없는 외부 라이브러리에서도 적용할 수 있다.
  • @Bean의 destroyMethod는 기본값이 추론으로 등록 되어 있다. close, shutdown이라는 이름의 메서드를 종료 메서드라고 추론해서 자동 호출해준다.

 

어노테이션 @PostConstruct, @PreDestroy

public class NetworkClient {
    @PostConstruct
    public void afterPropertiesSet() throws Exception {
    	connect();
    }

    @PreDestroy
    public void destroy() throws Exception {
    	disConnect();
    }
}
  • 어노테이션만 붙이면 작동한다.
  • 스프링이 아닌 다른 컨테이너에서도 동작한다.
  • 코드를 고칠 수 없는 외부 라이브러리에 적용할 수 없다.

 

 

출처

김영한 선생님 스프링 강의