@PostConstruct와 @PreDestroy 애너테이션은 약간 이론적인 내용이 있기 때문에 두 애너테이션의 역할이 무엇인지 알아보기 전에 스프링 빈의 생명주기를 먼저 알아보겠습니다.
1. 스프링 빈의 생명주기
- 스프링 컨테이너 생성
- 스프링 빈 생성
- 의존관계 주입
- 사용
- 스프링 종료
스프링 빈은 생성과 의존 관계 주입이 동시에 이루어지는 것이 아니라 스프링 빈 객체를 생성을 한 뒤에 의존관계 주입을 실행합니다.
이때 우리가 언제 의존관계 주입이 되는지, 또는 언제 스프링 빈이 소멸하는지를 알아보고 싶을 때 저 위의 두 애너테이션을 사용합니다.
두 애너테이션을 사용했을 때 생명주기를 나타내보자면
- 스프링 컨테이너 생성
- 스프링 빈 생성
- 의존관계 주입
- 초기화 콜백
- 사용
- 소멸 전 콜백
- 스프링 종료
이렇게 나타낼 수 있습니다.
초기화 콜백 : 빈이 생성되고, 빈의 의존관계 주입이 완료된 후 호출
소멸 전 콜백 : 빈이 소멸되기 직전에 호출
영어 뜻으로도 알 수 있다시피 @PostConstruct는 생성된 이후, @PreDestroy는 소멸 직전을 나타낸다고도 볼 수 있습니다.
import jakarta.annotation.PostConstruct;
import jakarta.annotation.PreDestroy;
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);
}
@PostConstruct
public void init() {
System.out.println("NetworkClient.init");
connect();
call("초기화 연결 메시지");
}
@PreDestroy
public void close() {
System.out.println("NetworkClient.close");
disconnect();
}
}
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class BeanLifeCycleTest {
@Test
public void lifeCycleTest() {
AnnotationConfigApplicationContext 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.dev");
return networkClient;
}
}
}
위의 두 코드를 통해 자세히 알아보겠습니다.
1. NetworkClient 메서드 실행
- "생성자 호출, url = null"
- connect 메서드 실행 >> connect: null
- call 메서드 실행 >> call: null message = 초기화 연결 메시지
2. init 메서드 실행 (스프링 빈의 의존관계 주입이 완료되었다는 것을 알 수 있습니다.)
- Networkclient.init 출력
- connect 메서드 실행 >> connect: http://hello.dev 출력
- call 메서드 실행 >> call: http://hello.dev message = 초기화 연결 메시지 출력
3. close 메서드 실행 (스프링 빈이 소멸되기 직전이라는 것을 알 수 있습니다.)
- NetworkClient.close 출력
- disconnect 메서드 실행 >> close : http:hello.dev
아래 실행 결과는 @PostConstruct, @preDestroy를 주석처리 했을 때 실행 결과입니다.
위의 결과와 비교했을 때 init, close 메서드가 실행이 안 되는 것을 볼 수 있습니다.
즉, 빈의 의존관계 주입이 언제 시작되는지, 언제 소멸되는지를 확인할 수가 없는 것을 알 수 있습니다.
출처 : 인프런 - 스프링 핵심 원리 (기본편)
'Spring > Spring' 카테고리의 다른 글
[Spring] 웹 서버, 웹 애플리케이션 서버 (0) | 2024.09.15 |
---|---|
[Spring] 빈 스코프 (0) | 2024.09.08 |
[Spring] 롬복 알아보기 (@RequiredArgsConstructor) (0) | 2024.09.04 |
[Spring] 의존관계 주입 방법 (0) | 2024.09.03 |
[Spring] 컴포넌트 스캔 (0) | 2024.09.02 |