yja
9. 빈 생명주기 콜백 본문
1. 빈 생명주기 콜백 시작
NetworkClient.java
여기서 생성자가 호출되면 `connect()` 를 통해 연결된 url을 확인할 수 있다.
public class NetworkClient {
private String url;
public NetworkClient() {
System.out.println("생성자 호출, url = " + url);
connect();
call("초기화 연결 메시지");
}
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);
}
}
lifeCycleTest.java
networkClient 객체를 만들고 나서, 값을 "http://hello-spring.dev"로 초기화한다.
@Test
public void lifeCycleTest() {
ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);
NetworkClient client = ac.getBean(NetworkClient.class);
ac.close();
}
@Configuration
static class LifeCycleConfig {
@Bean
public NetworkClient networkClient() {
NetworkClient networkClient = new NetworkClient();
networkClient.setUrl("http://hello-spring.dev");
return networkClient;
}
}
테스트 결과에는 connect가 null이 나온다. 왜 url이 설정되지 않았을까?

생성자 호출 시점에 url이 설정되지 않아서 null 이고, 그 상태에서 바로 connect()가 호출되기 때문이다.
객체 생성 후 setUrl() 을 통해 url 값이 세팅된다.
스프링 빈의 이벤트 라이프사이클
스프링 컨테이너 생성 ➡️ 스프링 빈 생성 ➡️ 의존관계 주입 ➡️ 초기화 콜백 ➡️ 사용 ➡️ 소멸전 콜백 ➡️ 스프링 종료
- 초기화 콜백: 빈이 생성되고, 빈의 의존관계 주입이 완료된 후 호출
- 소멸전 콜백: 빈이 소멸되기 직전에 호출
이런 콜백을 통해 안전하게 초기화와 종료가 될 수 있다.
객체 생성 시점과 초기화는 분리하는 게 좋다.
빈 생명주기 콜백을 지원하는 3가지 방법
1. 인터페이스(InitializingBean, DisposableBean)
2. 설정 정보에 초기화 메서드, 종료 메서드 지정
3. @PostConstruct, @PreDestroy 애노테이션 지원
2. 인터페이스 InitializingBean, DisposableBean
- InitializingBean`의`afterPropertiesSet()`: 초기화를 지원한다.
- DisposableBean`의`destroy()`: 메서드 소멸을 지원한다.
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
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();
}
}

하지만 이 방식은 스프링 전용 인터페이스이므로 수정하기 쉽지 않아서 좋지 않다.
3. 빈 등록 초기화, 소멸 메서드
위 방식 대신에 내가 직접 만든 메서드로 같은 기능을 구현할 수 있다.
이렇게 메서드를 직접 만들고,
public class NetworkClient {
// 의존관계 끝나고 호출되도록
public void init() throws Exception {
System.out.println("NetworkClient.init");
connect();
call("초기화 연결 메시지");
}
// 빈이 종료될 때 호출되도록
public void close() throws Exception{
System.out.println("NetworkClient.close");
disconnect();
}
}
@Bean 의 `initMethod`와 `destroyMethod`에 내가 만든 메서드 이름을 지정해준다.
@Bean(initMethod = "init", destroyMethod = "close")
public NetworkClient networkClient() {
NetworkClient networkClient = new NetworkClient();
networkClient.setUrl("http://hello-spring.dev");
return networkClient;
}

여기서 destroyMethod는 기본값이 "inferred"여서 `close`와 `shutdown` 라는 이름을 자동으로 추론하게 되어 정해주지 않아도 소멸 기능이 작동한다.

4. 애노테이션 @PostConstruct, @PreDestroy
- `@PostConstruct`: 빈의 의존관계 주입이 완료된 후에 호출된다.
- `@PreDestroy`: 스프링 컨테이너가 빈을 종료하기 직전에 호출된다.
자바 표준 기술이어서 스프링이 아닌 다른 컨테이너에서도 작동한다. -> 가장 권장되는 방식!
하지만 코드 수정은 하지 못한다.
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
public class NetworkClient {
// 의존관계 끝나고 호출됨
@PostConstruct
public void init() {
System.out.println("NetworkClient.init");
connect();
call("초기화 연결 메시지");
}
// 빈이 종료될 때 호출됨
@PreDestroy
public void close() {
System.out.println("NetworkClient.close");
disconnect();
}
}
사용하는 쪽에서는 @Bean으로 등록만 해주면 된다.
@Bean
public NetworkClient networkClient() {
NetworkClient networkClient = new NetworkClient();
networkClient.setUrl("http://hello-spring.dev");
return networkClient;
}

'[Web-Back] Spring > 스프링 핵심 원리 - 기본편 (강의)' 카테고리의 다른 글
| 10. 빈 스코프 (0) | 2026.05.04 |
|---|---|
| 8. 의존관계 자동 주입 (1) | 2026.04.27 |
| 7. 컴포넌트 스캔 (0) | 2026.04.06 |
| 6. 싱글톤 컨테이너 (1) | 2025.08.25 |
| 5. 스프링 컨테이너와 스프링 빈 (0) | 2025.07.26 |