빈 생명주기 콜백

Minseok Kim·2024년 2월 1일

Spring

목록 보기
11/13

스프링 빈의 이벤트 라이프사이클
스프링 컨테이너 생성 -> 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 -> 사용 -> 소멸전 콜백 -> 스프링 종료
초기화 콜백: 빈이 생성되고, 빈의 의존관계 주입이 완료된 후 호출
소멸전 콜백: 빈이 소멸되기 직전에 호출

빈 생명주기 콜백 3가지

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

인터페이스(InitializingBean, DisposableBean)

public class NetworkClient implements InitializingBean, DisposableBean {

    private String url;

	//의존관계 주입이 끝나면 연결해주겠다.
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("NetworkClient.afterPropertiesSet");
        connect();
        call("초기화 연결 메시지");
    }

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

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

}

InitializingBean은 의존관계 주입이 끝난 후 afterPropertiesSet() 메서드로 초기화를 지원
DisposableBean은 destroy() 메서드로 소멸을 지원한다.

단점

  • 이 인터페이스는 스프링 전용 인터페이스다. 해당 코드가 스프링 전용 인터페이스에 의존한다.
  • 초기화, 소멸 메소드를 오버라이딩 하기 때문에 메소드 이름을 변경할 수 없다.
  • 내가 코드를 고칠 수 없는 외부 라이브러리에 적용할 수 없다.

인터페이스를 사용하여 초기화 및 종료 방법은 스프링 초창기에 나온 방법들이며, 현재는 거의 사용하지 않음.


설정 정보에 초기화 메서드, 종료 메서드 지정

public class NetworkClient{

    //의존관계 주입이 끝나면 연결해주겠다.
    public void init() {
        //초기화 콜백, 의존관계 주입 후 호출
    	...
    }
    
    //종료될 때
    public void close() {
        //소멸 전 콜백
        ...
    }

public class BeanLifeCycleTest {

    @Configuration
    static class LifeCycleConfig{

        @Bean(initMethod = "init", destroyMethod = "close")
        public NetworkClient networkClient(){
            //생략
        }
    }
}

설정 정보 사용 특징

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

@Bean의 destroyMethod 속성의 기능
라이브러리는 대부분 종료 메소드 명이 close 혹은 shutdown이다.
@Bean의 destroyMethod 는 기본값이 inferred(추론)으로 등록되어 있다.
이 추론 기능은 close , shutdown 라는 이름의 메서드를 자동으로 호출해준다. 이름 그대로 종료 메서드를 추론해서 호출해준다.
즉, 종료 메서드를 추론하고 자동 호출해 줘 종료 메서드는 따로 적어주지 않아도 잘 동작한다.
@Bean(initMethod = "init", destroyMethod = "close")에서 close를 설정 안해줘도 잘 동작함


@PostConstruct, @PreDestroy 어노테이션 지원

public class NetworkClient{
	
    //의존관계 주입이 끝나면 연결해주겠다.
    @PostConstruct
    public void init() {
        //초기화 콜백, 의존관계 주입 후 호출
    	...
    }
    
    //종료될 때
    @PreDestroy
    public void close() {
        //소멸 전 콜백
        ...
    }
    
}

장점

  • 최신 스프링에서 가장 권장하는 방법
  • 어노테이션 하나만 붙이면 되므로 매우 편리함
  • 패키지가 javax.annotation.PostConstruct이라 스프링에 종속적인 기술이 아닌 JSR-250라는 자바 표준이다. 따라서 스프링이 아닌 다른 컨테이너에서도 동작
  • 컴포넌트 스캔과 잘 어울린다.

단점
유일한 단점은 외부 라이브러리에는 적용하지 못한다는 것이다. 외부 라이브러리를 초기화, 종료 해야 하면 @Bean의 기능을 사용하자.

정리
@PostConstruct, @PreDestroy 애노테이션을 사용하자

출처
김영한 스프링 핵심 원리 - 기본편

0개의 댓글