[TIL] 빈 생명주기 콜백

SSOYEONG·2022년 5월 19일
0

스프링 기본

목록 보기
7/7
post-thumbnail

빈 생명주기 콜백 시작

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

  • Bean 생명주기
    Bean 객체가 생성되어 소멸되기 전까지의 모든 과정

  • 스프링은 의존관계 주입이 완료되면 스프링빈에게 콜백 메서드를 통해서 초기화 시점을 알려주는 다양한 기능을 제공

  • 스프링은 스프링 컨테이너가 종료되기 직전에 소멸 콜백을 준다.

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

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

  • 소멸 전 콜백
    빈이 소멸되기 직전에 호출

  • 스프링은 크게 3가지 방법으로 빈 생명주기 콜백을 지원한다.

1. 인터페이스 Initializing Bean, Disposable Bean

public class NetworkClient implements InitializingBean, DisposableBean {

    private String url;

    public NetworkClient(){
        System.out.println("생성자 호출, url = " + url);
    }

    public void setUrl(String url){
        this.url = url;
    }

    // 서비스 시작 시 호출
    public void connect(){
        System.out.println("connect: " + url);
    }

    public void call(String message){
        System.out.println("call: " + url + ", message: " + message);
    }

    // 서비스 종료 시 호출
    public void disconnect(){
        System.out.println("close: " + url);
    }

    @Override
    public void afterPropertiesSet() throws Exception {     // DI가 끝나면 실행됨
        connect();
        call("초기화 연결 메시지");
    }

    @Override
    public void destroy() throws Exception {        // Bean 종료 후 실행됨
        disconnect();
    }
}
  • InitializingBeanafterPropertiesSet() 메서드로 초기화를 지원
  • DisposableBeandestroy() 메서드로 소멸을 지원

단점

  • 스프링 전용 이터페이스에 의존한다.
  • 초기화, 소멸 메서드의 이름을 변경할 수 없다.
  • 내가 코드를 고칠 수 없는 외부 라이브러리에 적용할 수 없다.
  • 지금은 더 나은 방법들이 있어서 거의 사용하지 않는다.

2. 빈 등록 초기화, 소멸 메서드 지정

  • 설정 정보에 @Bean(initMethod = "init", destroyMethod = "close"로 초기화, 소멸 메서드를 지정할 수 있다.
public class BeanLifeCycleTest {

    @Test
    public void lifeCycleTest(){
        ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);
        NetworkClient client = ac.getBean(NetworkClient.class);
        ac.close();
    }

    @Configuration
    static class LifeCycleConfig {

        @Bean(initMethod = "init", destroyMehotd = "close")	// 추가됨 !!
        public NetworkClient networkClient(){
            NetworkClient networkClient = new NetworkClient();
            networkClient.setUrl("http://hello-spring.dev");
            return networkClient;
        }
    }
}

설정 정보 사용 특징

  • 메서드 이름을 자유롭게 설정할 수 있다,
  • 스프링 빈이 스프링 코드에 의존하지 않는다.
  • 코드가 아니라 설정 정보를 사용하기 때문에 코드를 고칠 수 없는 외부 라이브러리에도 초기화, 종료 메서드를 적용할 수 있다.

종료 메서드 추론

  • 라이브러리는 대부분 close, shutdown이라는 이름의 종료 메서드를 사용한다.
  • @Bean의 destroyMethod는 기본값이 (inferred)로 등록되어 있다.
  • 이 추로 기능은 close, shutdown이라는 이름의 메서드를 자동으로 호출해준다.
  • 즉, 이름 그대로 종료 메서드를 추론해서 호출한다.

3. 애노테이션 @PostConstruct, @PreDestroy

  • @PostConstruct, @PreDestroy 이 두 애노테이션을 사용하면 가장 편리하게 초기화와 종료를 실행할 수 있다.
public class NetworkClient {

    private String url;

    public NetworkClient(){
        System.out.println("생성자 호출, url = " + url);
    }

    public void setUrl(String url){
        this.url = url;
    }

    // 서비스 시작 시 호출
    public void connect(){
        System.out.println("connect: " + url);
    }

    public void call(String message){
        System.out.println("call: " + url + ", message: " + message);
    }

    // 서비스 종료 시 호출
    public void disconnect(){
        System.out.println("close: " + url);
    }

    @PosstConstruct
    public void init(){
    	System.out.println("NetwrokClient.init");
        connect();
        call("초기화 연결 메시지");
    }
    
    @PreDestroy
    public void close(){
    	System.out.println("NetworkClient.close");
        disConnect();
    }
}

특징

  • 최신 스프링에서 가장 권장하는 방법
  • 애노테이션 하나만 붙이면 되므로 매우 편리
  • 스프링 종속 x, 자바 표준 o
  • 단점은 외부 라이브러리에 적용 불가능 > 이때는 @Bean의 기능을 사용하자.

정리

  • @PostContruct, @PreDestroy 애노테이션을 사용하자
  • 코드를 고칠 수 없는 외부 라이브러리를 초기화, 종료해야 하면 @BeaninitMethod, destroyMethod를 사용하자

Reference
인프런 - 김영한님의 [스프링 핵심 원리 - 기본편] 수강 후 강의노트를 바탕으로 작성한 글입니다.
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard

profile
Übermensch

0개의 댓글