빈 생명주기 보충자료

스프링 빈 생명주기

스프링에서 빈 생명주기는 객체 생성부터 소멸까지의 과정을 관리하며, 애플리케이션 실행 시 필요한 자원을 초기화하거나 종료하는 작업을 처리할 수 있습니다. 특히, 데이터베이스 커넥션 풀이나 네트워크 소켓과 같은 리소스를 애플리케이션 시작 시 준비하고 종료 시 정리하는 데 활용됩니다.


빈의 생명주기 단계

  1. 컨테이너 생성

    • 스프링 컨테이너가 생성됩니다.

  2. 빈 생성

    • 스프링 컨테이너가 빈 객체를 생성합니다.

  3. 의존관계 주입

    • 빈에 필요한 의존관계가 모두 주입됩니다.

  4. 초기화 콜백

    • 의존관계 주입이 완료된 후 초기화 작업을 수행할 수 있는 시점입니다.

    • 데이터베이스 연결, 네트워크 소켓 연결 등을 초기화할 수 있습니다.

  5. 빈 사용

    • 애플리케이션에서 빈을 사용합니다.

  6. 소멸 전 콜백

    • 스프링 컨테이너가 종료되기 직전에 빈을 정리합니다.

    • 데이터베이스 연결 해제, 네트워크 소켓 종료 등을 수행합니다.

  7. 스프링 종료

    • 스프링 컨테이너가 종료됩니다.


초기화 및 소멸 처리 방법

1. 인터페이스 구현

InitializingBeanDisposableBean 인터페이스를 구현하여 초기화와 소멸 작업을 처리합니다.

예시 코드

@Component
public class NetworkClient implements InitializingBean, DisposableBean {

    private String url;

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

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

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

    @Override
    public void destroy() throws Exception {
        System.out.println("NetworkClient 종료");
        disconnect();
    }

    public void connect() {
        System.out.println("Connecting to " + url);
    }

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

    public void disconnect() {
        System.out.println("Disconnecting from " + url);
    }
}

특징

  • afterPropertiesSet(): 초기화 시 호출됩니다.

  • destroy(): 소멸 시 호출됩니다.


2. 애노테이션 사용 (@PostConstruct, @PreDestroy)

스프링에서는 @PostConstruct@PreDestroy 애노테이션을 통해 초기화 및 소멸 콜백을 처리할 수 있습니다.

예시 코드

@Component
public class DatabaseClient {

    private String url;

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

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

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

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

    public void connect() {
        System.out.println("Connecting to " + url);
    }

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

    public void disconnect() {
        System.out.println("Disconnecting from " + url);
    }
}

특징

  • @PostConstruct: 의존관계 주입이 완료된 후 호출됩니다.

  • @PreDestroy: 컨테이너가 종료되기 직전에 호출됩니다.

  • 권장 방식: 스프링이 아닌 다른 컨테이너에서도 동작하며, 간결하고 사용하기 쉽습니다.


3. 빈 등록 메서드에 초기화 및 소멸 메서드 지정

XML 또는 Java Config 방식으로 초기화와 소멸 메서드를 직접 지정할 수 있습니다.

예시 코드

@Configuration
public class AppConfig {

    @Bean(initMethod = "init", destroyMethod = "close")
    public NetworkClient networkClient() {
        NetworkClient networkClient = new NetworkClient();
        networkClient.setUrl("http://example.com");
        return networkClient;
    }
}

특징

  • initMethoddestroyMethod 속성을 사용하여 초기화와 소멸 메서드를 지정합니다.

  • 외부 라이브러리의 초기화 및 소멸 작업에 주로 사용됩니다.


초기화와 소멸 관리 시 주의사항

  1. 외부 라이브러리 관리

    • 외부 라이브러리에서 초기화와 종료가 필요한 경우, 인터페이스나 애노테이션 대신 빈 등록 시 초기화 및 소멸 메서드를 지정하는 방식을 사용합니다.

  2. @PostConstruct와 @PreDestroy 사용 권장

    • 간단한 초기화와 종료 작업에는 @PostConstruct@PreDestroy를 사용하는 것이 가장 간편하고 권장됩니다.

  3. 무거운 작업 처리

    • 초기화와 종료 작업은 가능한 빠르게 처리해야 하며, 너무 많은 작업이 포함되지 않도록 주의해야 합니다.

  4. 빈의 상태 관리

    • 초기화 작업은 의존관계 주입이 완료된 상태에서만 동작해야 합니다.


요약

스프링 빈의 생명주기를 활용하여 데이터베이스 커넥션 풀, 네트워크 소켓 등의 리소스를 효율적으로 관리할 수 있습니다.

  • 일반적으로 @PostConstruct@PreDestroy를 사용하여 초기화와 종료 작업을 처리합니다.

  • 외부 라이브러리 관리가 필요한 경우, initMethoddestroyMethod를 지정하는 방식을 사용할 수 있습니다.

  • 빈 생명주기를 올바르게 활용하면 애플리케이션의 안정성과 자원 관리를 효과적으로 개선할 수 있습니다.

Last updated