Home 빈 생명주기(Bean Lifecycle)
Post
Cancel

빈 생명주기(Bean Lifecycle)

빈 생명주기

스프링 컨테이너는 빈 객체를 생성하고, 프로퍼티를 할당하고, 초기화를 수행하고, 사용이 끝나면 소멸시키는 일련의 과정을 관리한다.

스프링 빈은 객체를 생성하고, 의존관계 주입이 다 끝난 다음에야 필요한 데이터를 사용할 수 있는 준비가 완료된다. 스프링은 의존관계 주입이 완료되면 스프링 빈에게 콜백 메서드를 통해서 초기화 시점을 알려주는 다양한 기능을 제공한다. 또한 스프링은 컨테이너가 종료되기 직전에 소멸 콜백을 준다.

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

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

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

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

인터페이스(InitializingBean, DisposableBean)

InitializingBeanDisposableBean 인터페이스를 구현해서 빈을 작성하는 방법이다. InitializingBeanafterPropertiesSet() 메서드는 이름 그대로 프로퍼티 설정까지 마친 뒤에 호출된다. 그리고 DisposableBeandestroy() 메서드는 빈이 소멸 되기 직전에 호출된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
public class BeanLifecycle implements InitializingBean, DisposableBean {
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("afterPropertiesSet");
        System.out.println("프로퍼티 설정까지 마친 뒤에 호출");
    }

    @Override
    public void destroy() throws Exception {
        System.out.println("destroy");
        System.out.println("빈이 소멸 되기 직전에 호출");
    }
}

이 방법은 별로 권장되지 않는다. 애플리케이션 빈 코드에 스프링 인터페이스를 노출하기 때문이다. 또 다른 방법이 더 간결하기 때문이기도 하다. 반면에 인터페이스를 보고 코드의 동작방식을 이해하기 쉽다는 장점도 있다.

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

1
2
3
4
5
6
7
8
9
10
11
12
public class BeanLifecycle {

    public void init() throws Exception {
        System.out.println("init");
        System.out.println("프로퍼티 설정까지 마친 뒤에 호출");
    }

    public void close() throws Exception {
        System.out.println("close");
        System.out.println("빈이 소멸 되기 직전에 호출");
    }
}
1
2
3
4
5
6
7
8
@Configuration
public class LifecycleConfig {

    @Bean(initMethod = "init", destroyMethod = "close")
    public BeanLifecycle beanLifecycle() {
        return new BeanLifecycle();
    }
}

초기화 콜백 인터페이스를 사용히는 방법과 달리 빈 클래스에 스프링 API가 노출되지 않기 때문에 깔끔하다는 장점이 있는 반면 코드만 보고는 초기화 메소드가 호출될지 알 수 없기 때문에 코드를 이해하는 데 불편할 수 있다.

@PostConstruct, @PreDestroy 어노테이션

이 방법은 어노테이션을 활용한 방법으로 초기화를 담당할 메서드에 @PostConstruct 종료를 담당할 메서드에 @PreDestroy를 붙여주면 된다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class BeanLifecycle {

    @PostConstruct
    public void init() throws Exception {
        System.out.println("init");
        System.out.println("프로퍼티 설정까지 마친 뒤에 호출");
    }

    @PreDestroy
    public void close() throws Exception {
        System.out.println("close");
        System.out.println("빈이 소멸 되기 직전에 호출");
    }
}

이 방법은 최신 스프링에서 가장 권장하는 방법이다. 그리고 어노테이션 하나만 붙이면 되므로 매우 편리하다. 단점은 외부 라이브러리에 적용하지 못한다는 점이다. 만약 외부 라이브러리의 코드를 수정할 수 없지만 초기화, 종료 작업이 필요하다면 @Bean(initMethod = "init", destroyMethod = "close") 기능을 활용하면 된다.

참고

This post is licensed under CC BY 4.0 by the author.

다양한 의존관계 주입

빈 스코프

Comments powered by Disqus.