쌓고 쌓다

빈 생명주기 콜백 본문

프로그래밍/spring

빈 생명주기 콜백

승민아 2023. 7. 16. 17:06

DB 커넥션 풀 등..

애플리케이션 시작 시점에 미리 연결하고 (초기화 작업)

애플리케이션 종료 시점에 연결을 모두 종료하는 (종료 작업) 작업을 위해 어떻게하면 될까?

 

스프링 빈 라이프사이클

  1. 객체 생성
  2. 의존관계 주입

스프링 빈은 객체 생성을하고 의존관계 주입 이후에 사용할 수 있는 준비가 완료된다.

초기화 작업은 의존관계 주입이 끝난 후 이뤄져야한다.

*생성자 주입의 경우 빈 생성과 동시에 의존관계 주입이 이뤄진다.

 

객체의 생성때 초기화 작업을 함께하면 되는거 아니야?

생성자는 필수 정보를 받고 객체를 생성하는 책임을 갖는다.

초기화는 정보들을 가지고 외부 커넥션을 연결하는 등 무거운 작업을 이룬다.

따라서 생성자 안에서 함께 이뤄지는 것 보다 생성과 초기화를 나누는것이 유지보수에 좋다.

 

 

 

이 초기화 작업의 시점은 어떻게 알 수 있을까?

스프링은 의존관계 주입이 끝난 후 스프링 빈에게 콜백 메서드를 통해 초기화 시점을 알려준다.

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

우리는 이 콜백을 통해 초기화와 종료 작업을 수행할 수 있다.

 

스프링 빈 라이프사이클

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

 

*초기화 콜백: 의존관계 주입 이후 호출, 소멸 콜백: 빈 소멸전 호출

 

스프링 빈 생명주기 콜백

  • 인터페이스(InitializingBean, DisposableBean)
  • 설정 정보에 초기화, 종료 메소드 지정
  • @PostConstruct, @PreDestroy 어노테이션

@PostConstruct, @PreDestory 방법을 스프링에서 권장하는 방법이므로 이 방법만 알아보자.

 

BeanLifeCycleTest

public class BeanLifeCycleTest {

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

    @Configuration
    static class LifeCycleConfig {

        @Bean
        public NetworkClient networkClient() {
            NetworkClient networkClient = new NetworkClient();
            networkClient.setUrl("www.naver.com");
            return networkClient;
        }
    }
}

networkClient 스프링 빈이 생성되고 의존관계 주입이 이뤄진 후 초기화 작업과 종료 작업을 이뤄지게 만들어 보자.

 

+ApplicationContext 인터페이스에는 ApplicationContext를 닫는 close() 메소드를 제공하지 않는다.

ApplicationContext를 포함하는 ConfigurableApplicationContext로 받거나 AnnotationConfig...Context로 받자.

 

 

@PostConstruct : 초기화 메서드 등록

@PreDestory : 종료 메서드 등록

 

 

NetworkClient

import jakarta.annotation.PostConstruct;
import jakarta.annotation.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 disconnect() {
        System.out.println("close : " + url);
    }

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

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

    @PreDestroy
    public void close() {
        System.out.println("NetworkClient.close");
        disconnect();
    }

}

빈 등록을 위해 생성자 호출시에는 url이 설정되어 있지 않을 것이다. 

이후 빈 등록하고 의존관계 주입이 이뤄진 후 init 메서드를 통해 초기화 작업을 동작하고

close 메소드를 통해 종료 작업이 동작한다.

 

출력 결과

빈 등록과 의존관계 주입 시점에 url은 null 이고

의존관계 주입 이후에 @PostConstruct 메서드로 초기화 작업 실행하고

ApplicationContext가 종료되기전 @PreDestroy 메서드로 종료 작업 실행된다.

 

 

 

 

 

 

Comments