[Spring] 빈 생명주기 콜백 (@PostConstruct, @PreDestroy)

728x90

 

빈 생명주기 콜백

 

스프링이 기본적으로 생성하는 싱글톤 스코프로 설명을 이어나가겠다.

 

스프링 빈은 생성된 후 바로 사용할 수 없고, 특정 빈은 초기화 과정이 필요하다.

(ex: DB 연결, 네트워크 연결 등)

또한 스프링 빈은 컨테이너가 종료되기 전 자원을 안전하게 해제하는 소멸 과정이 필요하다.

 

초기화 콜백, 소멸 콜백

초기화 콜백 : 스프링이 의존관계 주입을 완료하면 스프링 빈에게 콜백 메서드를 통해 초기화 시점을 알려준다.

소멸 콜백 : 스프링 컨테이너가 종료되기 직전에 알려준다.

 

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

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

 

> 참고 <

- 객체의 생성과 초기화는 분리하는 것이 좋다.

(단순한 경우 X, 외부 커넥션 연결하는 등 무거운 동작 수행할 때 O)

 

빈 생명주기 콜백을 지원하는 방법

- 인터페이스 (InitializingBean, DisposableBean) (거의 사용 X)

- 설정 정보에 초기화 메서드, 종료 메서드 지정 (특정 상황에서)

- @PostConstruct, @PreDestroy 애노테이션 지원 (권장)

 

인터페이스 (InitializingBean, DisposableBean) (거의 사용 X)

InitializingBean : afterPropertiesSet() 메서드로 초기화를 지원한다.

DisposableBean : destroy() 메서드로 소멸을 지원한다.

 

public class NetworkClient implements InitializingBean, DisposableBean {
  
  // 서비스 시작시 호출
  public void connect() {
  }
  
  // 서비스 종료시 호출
  public void disConnect() {
  }
  
  @Override
  public void afterPropertiesSet() throws Exception {
    connect();
  }
  
  @Override
  public void destroy() throws Exception {
    disConnect();
  }
}

 

단점

- 스프링 전용 인터페이스이므로 해당 코드가 스프링 전용 인터페이스에 의존한다.

- 초기화, 소멸 메서드의 이름을 변경할 수 없다.

- 코드를 고칠 수 없는 외부 라이브러리에 적용할 수 없다.

 

설정 정보에 초기화 메서드, 종료 메서드 지정 (특정 상황에서)

설정 정보에 @Bean(initMethod = "init", destroyMethod = "close") 처럼 초기화, 소멸 메서드를 지정할 수 있다.

public class NetworkClient {
  
  // 서비스 시작시 호출
  public void connect() {
  }
  
  // 서비스 종료시 호출
  public void disConnect() {
  }
  
  public void init() {
    connect();
  }
  
  public void close() {
    disConnect();
  }
}
@Configuration
static class LifeCycleConfig {

  @Bean(initMethod = "init", destroyMethod = "close")
  public NetworkClient networkClient() {
    return new NetworkClient();
  }
}

 

장점

- 메서드 이름을 자유롭게 설정 가능하다.

- 스프링 빈이 스프링 코드에 의존하지 않는다.

- 코드가 아닌 설정 정보를 사용하기 때문에 코드를 고칠 수 없는 외부 라이브러리에도 초기화, 종료 메서드를 적용할 수 있다.

 

@Bean destoryMethod 속성

대부분의 라이브러리의 종료 메서드 이름은 close, shutdown 이다.

@Bean destoryMethod 는 기본값이 (inferred) 로 등록되어 close, shutdown 라는 메서드를 자동 호출 해준다.

따라서 직접 스프링 빈으로 등록하면 종료 메서드는 따로 적지 않아도 잘 동작한다.

추론 기능을 사용하지 않으려면 destoryMethod="" 처럼 빈 공백을 지정하면 된다.

 

> 참고 <

- 설정 정보에 초기화, 소멸 메서드 지정 방법은 수동 등록 방법에서만 사용할 수 있다.

(@Component 에는 해당 기능 지원 X)

 

@PostConstruct, @PreDestroy 애노테이션 지원 (권장)

@PostConstruct, @PreDestory 애노테이션을 사용하면 가장 편리하게 초기화, 종료 메서드를 실행할 수 있다.

public class NetworkClient {
  
  // 서비스 시작시 호출
  public void connect() {
  }
  
  // 서비스 종료시 호출
  public void disConnect() {
  }
  
  @PostConstruct
  public void init() {
    connect();
  }
  
  @PreDestroy
  public void close() {
    disConnect();
  }
}
@Configuration
static class LifeCycleConfig {

  @Bean
  public NetworkClient networkClient() {
    return new NetworkClient();
  }
}

 

장점

- 최신 스프링에서 가장 권장하는 방법이다.

- 애노테이션 하나만 붙이면 되므로 매우 편리하다.

- JSR-250(자바 표준) 이므로 스프링이 아닌 다른 컨테이너에서도 동작한다.

- 자동 빈 등록(@Component)과 함께 사용 가능하다.

 

단점

- 외부 라이브러리에는 적용하지 못한다. 

(이러한 경우에는 @Bean(initMethod, destroyMethod) 기능을 사용한다.)

 

 

 

 

 

 

 

 

출처 | 스프링 핵심 원리 - 기본편(김영한) - 인프런

 
728x90