데이터베이스 커넥션 풀이나, 네트워크 소켓처럼 애플리케이션 시작 시점에 필요한 연결을 미리 해두고, 애플리케이션 종료 시점에 연결을 모두 종료하는 작업을 진행하려면, 객체의 초기화
와 종료
작업이 필요함
✅ 스프링 빈의 라이프 사이클
객체 생성 -> 의존관계 주입
스프링 빈은 객체를 생성하고, 의존관계 주입
이 다 끝난 다음에야
필요한 데이터를 사용할 수 있는 준비가 완료된다
초기화 작업
은 의존관계 주입이 모두 완료되고 난 다음에 호출해야 한다
그런데 개발자는 의존관계 주입
이 모두 완료된 시점을 언제 알 수 있을까?
-> 스프링은 의존관계 주입
이 완료되면 스프링 빈에게 콜백 메서드
를 통해서 초기화 시점을 알려주는 다양한 기능을 제공한다
-> 추가로 스프링은 스프링 컨테이너
가 종료되기 직전에 소멸 콜백
을 줘서 안전하게 종료 작업 진행 가능
✅ 스프링 빈의 이벤트 라이프 사이클
스프링 컨테이너 생성
-> 스프링 빈 생성
-> 의존관계 주입
-> 초기화 콜백
-> 사용
-> 소멸전 콜백
-> 스프링 종료
초기화 콜백
: 빈이 생성되고, 빈의 의존관계 주입이 완료된 후 호출소멸전 콜백
: 빈이 소멸되기 직전에 호출스프링은 크게 3가지 방법으로 빈 생명주기 콜백 을 지원
InitializingBean
, DisposableBean
)@PostConstruct
, @PreDestroy
애노테이션 지원 -> 최근 기술로 이거 사용하는 것이 좋음InitializingBean
인터페이스 구현체 -> afterPropertiesSet()
메서드 = 초기화를 지원DisposableBean
인터페이스 구현체 -> destroy()
메서드 = 소멸을 지원코드
public class NetworkClient implements InitializingBean, DisposableBean {
//...
@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 class NetworkClient {
//...
public void init() {
System.out.println("NetworkClient.init");
connect();
call("초기화 연결 메시지");
}
public void close() {
System.out.println("NetworkClient.close");
disconnect();
}
}
설정 정보에 @Bean(initMethod
= "init", destroyMethod
= "close")처럼 초기화, 소멸 메서드를 지정가능
class BeanLifeCycleTest {
//...
@Configuration
static class LifeCycleConfig {
@Bean(initMethod = "init", destroyMethod = "close") // bean으로 초기화, 소멸 지정
public NetworkClient networkClient() {
NetworkClient networkClient = new NetworkClient();
networkClient.setUrl("http://hello-spring.dec");
return networkClient;
}
}
}
출력 결과
종료 메소드 추론
@Bean
의 destroyMethod
속성에는 아주 특별한 기능이 있다.close
, shutdown
이라는 이름의 종료 메서드를 사용한다.@Bean
의 destroyMethod
는 기본값이 (inferred)
(추론)으로 등록되어 있다.close
, shutdown
이라는 이름의 메서드를 자동으로 호출스프링 빈
으로 등록하면 종료 메서드는 따로 적어주지 않아도 잘 동작한다.@Bean
의 initMethod
와 destroyMethod
사용하자