[TIL #35] 빈 생명주기 콜백

2024. 12. 6. 20:30·개발/내일배움캠프 TIL

스프링 빈의 이벤트 라이프사이클

  1. 스프링 컨테이너 생성
  2. 스프링 빈 생성
  3. 의존관계 주입
  4. 초기화 콜백
  5. 객체 사용
  6. 소멸 전 콜백
  7. 스프링 종료

이와 같이 객체의 메서드들이 실제로 실행되기 위해선 3. 의존관계 주입까지 마치고 나서 필드 초기화가 진행되야한다. 그렇기에 이 시작시점과 종료시점을 지정할 수 있는 방법들을 알아봤다.

 

  1. 인터페이스(InitializingBean, DisposableBean)
  2. 설정 정보에 초기화 메서드, 종료 메서드 지정
  3. @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
'개발/내일배움캠프 TIL' 카테고리의 다른 글
  • [TIL #37] JPA를 이용한 일정 과제를 하면서 배운 내용 + 트러블 슈팅 기록
  • [TIL #36] Spring 에서의 검증
  • [TIL #33] 컴포넌트 스캔 탐색 위치와 기본 스캔 대상
  • [TIL #32] Spring 일정 관리 앱 과제 트러블 슈팅 + 디버그로 원인 찾기
BigChoi93
BigChoi93
이곳은 저의 성장과정과 개인적인 생각을 담기 위한 공간입니다.
  • BigChoi93
    Donologue
    BigChoi93
  • 전체
    오늘
    어제
    • 분류 전체보기 (61)
      • 개발 (53)
        • Javascript (2)
        • 내일배움캠프 TIL (41)
        • 개발일기 (4)
        • Java (2)
        • Spring (1)
        • Sql (1)
      • 일상 (0)
      • 사진 (1)
        • 포토샵 (1)
  • hELLO· Designed By정상우.v4.10.1
BigChoi93
[TIL #35] 빈 생명주기 콜백
상단으로

티스토리툴바