데이터베이스 커넥션 풀, 네트워크 소켓 등 애플리케이션 시작 시점에 필요한 연결을 미리 설정하고, 종료 시점에 끊어야 할 때 빈의 생명주기 콜백을 활용할 수 있습니다. 빈 생명주기 콜백은 객체가 생성되고 의존성 주입이 완료된 후 초기화 작업을 진행하며, 종료 시점에는 소멸 작업을 수행합니다.

1. 빈 생명주기 과정

스프링 빈은 객체 생성, 의존관계 주입, 초기화 콜백, 사용, 소멸 전 콜백의 순서로 라이프사이클이 진행됩니다. 초기화 작업은 의존관계 주입이 완료된 후 수행해야 하며, 소멸 작업은 빈이 종료되기 직전에 진행됩니다.

스프링은 빈 생명주기 콜백을 지원하는 여러 방법이있습니다.

2.1. 인터페이스 InitializingBean, DisposableBean

InitializingBean 인터페이스의 afterPropertiesSet() 메서드를 통해 초기화 작업을 수행할 수 있고, DisposableBean 인터페이스의 destroy() 메서드를 통해 소멸 작업을 수행할 수 있습니다.


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 {
        connect();
        call("초기화 연결 메시지");
    }
    @Override
    public void destroy() throws Exception {
        disConnect();
    }
}

2.2. @Bean 애노테이션의 initMethoddestroyMethod

스프링 설정 파일에서 **@Bean(initMethod = "init", destroyMethod = "close")**와 같이 초기화 메서드와 소멸 메서드를 지정할 수 있습니다. 이를 통해 객체의 초기화와 종료 작업을 설정할 수 있습니다. 예를 들어, 아래와 같이 설정할 수 있습니다.


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);
    }

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

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


@Configuration
static class LifeCycleConfig {
    @Bean(initMethod = "init", destroyMethod = "close")
    public NetworkClient networkClient() {
        NetworkClient networkClient = new NetworkClient();
        networkClient.setUrl("<http://dongwook>");
        return networkClient;
    }
}

2.3. @PostConstruct, @PreDestroy 에너테이션

현재 스프링에서는 @PostConstruct@PreDestroy 에너테이션을 사용하여 초기화 및 소멸 작업을 수행할 수 있습니다. 이 방법은 가장 간단하고 편리하게 빈의 생명주기를 관리할 수 있습니다.


import javax.annotation.PostConstruct;
import javax.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 call(String message) {
        System.out.println("call: " + url + " message = " + message);
    }

    public void disConnect() {
        System.out.println("close: " + url);
    }

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

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

3. 결론

스프링 빈의 초기화 및 종료 작업을 관리하는 방법으로는 InitializingBean, DisposableBean, @Bean 에너테이션의 initMethod, destroyMethod, 그리고 @PostConstruct, @PreDestroy 에너테이션이 있습니다. 이 중에서 현재 스프링에서는 @PostConstruct@PreDestroy 에너테이션을 사용하는 방법이 가장 추천됩니다. 왜냐면 간단하잖아요 그죠?