스프링 빈의 이벤트 라이프사이클
- 스프링 컨테이너 생성
- 스프링 빈 생성
- 의존관계 주입
- 초기화 콜백
- 객체 사용
- 소멸 전 콜백
- 스프링 종료
이와 같이 객체의 메서드들이 실제로 실행되기 위해선 3. 의존관계 주입까지 마치고 나서 필드 초기화가 진행되야한다. 그렇기에 이 시작시점과 종료시점을 지정할 수 있는 방법들을 알아봤다.
- 인터페이스(InitializingBean, DisposableBean)
- 설정 정보에 초기화 메서드, 종료 메서드 지정
- @PostConstruct, @PreDetroy 에노테이션
일단 3가지 방법 중 결론은 3. 에노테이션을 쓰는 것인데 왜 그런지 알아보자.
1. 인터페이스 (InitializingBean, DisposableBean)
인터페이스이므로 객체 클래스 뒤에 `implements` 로 붙여 사용할 수 있다.
package hello.core.lifecycle;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class NetworkClient implements InitializingBean, DisposableBean {
private String url;
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);
}
@Override
public void afterPropertiesSet() throws Exception {
connect();
call("초기화 연결 메시지");
}
@Override
public void destroy() throws Exception {
disConnect();
}
코드를 보면 `@Override` 된 `afterPropertiesSet()` 와 `destroy()` 메서드가 있는데 이것이 시작과 종료 시점을 지정한다.
이렇게 보면 간단해보이는데 단점이 무엇인지 알아보자.
- 스프링 전용 인터페이스
import 해오는 코드에서도 확인할 수 있듯이 스프링 전용 인터페이스로 여기에 의존하게 되며, 그렇다는건 제공되는 메서드의 이름도 변경할 수 없고, 내가 수정할 수 없는 외부 라이브러리의 객체에는 사용할 수 없다는 것이다. 결론은 유연성이 떨어진다.
2. 빈 등록 초기화, 소멸 메서드 지정
스프링 빈을 지정하는 에노테이션에서 초기화와 소멸 시점을 지정할 수 있다.
public void init() throws Exception {
connect();
call("초기화 연결 메시지");
}
public void close() throws Exception {
disConnect();
}
일단 위 코드에서 초기화 와 소멸 시점에 실행될 메서드를 작성한다.
@Bean(initMethod = "init", destroyMethod = "close")
public NetworkClient networkClient() {
NetworkClient networkClient = new NetworkClient();
networkClient.setUrl("http://hello-spring.dev");
return networkClient;
}
그리고 `@Bean` 에노테이션 뒤에 메서드 이름을 다음과 같이 넣어주면 완료된다.
이렇게 보니 확실히 1번보다 나아보이는게 일단 객체가 어디에도 의존하지 않고 있다. 그와 동시에 메서드 이름도 자유롭게 정할 수 있고 설정 정보를 사용하기 때문에 외부 라이브러리에도 적용을 할 수 있다.
* 여기서 외부 라이브러리는 대부분 close, shutdown 이라는 이름으로 종료 메서드를 사용하는데 destoryMethod 속성의 기본값에 이러한 이름이 포함되어 있기 때문에 이런 경우 종료 메서드를 따로 적어주지 않아도 잘 작동한다.
그럼 왜 이제 3번을 써야하는 지 알아보자.
3. @PostConstruct, @PreDestroy
@PostConstruct
public void init() {
connect();
call("초기화 연결 메시지");
}
@PreDestroy
public void close() {
disConnect();
}
이 방법은 일단 최신 스프링에서 권장하는 방법이며, 그냥 필요한 시점에 에노테이션만 붙여주면 끝이기 때문에 매우 편리하다. 그리고 이 에노테이션은 자바 표준으로 1번의 단점을 보완해주고 2번보다 깔끔하고 편하게 사용할 수 있는 것을 알 수 있다.
근데 유일한 단점은 1번와 같이 외부 라이브러리에 사용할 수 없다는 것이기 때문에 이런 경우에만 2번을 사용하면 된다.
'개발 > 내일배움캠프 TIL' 카테고리의 다른 글
[TIL #37] JPA를 이용한 일정 과제를 하면서 배운 내용 + 트러블 슈팅 기록 (0) | 2024.12.18 |
---|---|
[TIL #36] Spring 에서의 검증 (0) | 2024.12.13 |
[TIL #33] 컴포넌트 스캔 탐색 위치와 기본 스캔 대상 (0) | 2024.12.04 |
[TIL #32] Spring 일정 관리 앱 과제 트러블 슈팅 + 디버그로 원인 찾기 (0) | 2024.12.03 |
[TIL # 31] SQL 타입과 함수 (0) | 2024.12.02 |