빈 생명주기 콜백
💡 애플리케이션 시작 시, 필요한 연결을 미리 해두는 작업이 필요하다. 애플리케이션 종료 시, 객체의 초기화 및 종료작업이 필요하다. 콜백의 종류에는 2가지가 있다.
1. 초기화 콜백
- 빈(Bean)의 생성과 의존관계 주입이 완료되고 완료 되었다고 호출 되는 작업
- 초기화 작업은 반드시 빈 생성 및 의존 관계 주입이 모두 완료된 후에 시작 되어야 한다.
→ 의존 관계 주입이 된 빈들을 미리 세팅 해야 하기 때문! - 개발자가 이 시점을 알기 위해 필요한 것이
초기화 콜백 메서드
이다.
2. 소멸 콜백
- 애플리케이션 종료 시점에 연결을 모두 종료하는 작업을 진행하기 위한 과정
- 개발자가 이 시점을 알기 위해 필요한 것이
종료 콜백 메서드
💡 객체의 생성과 초기화를 분리해야 하는 이유?
- 객체를 생성하는 부분과 초기화 하는 부분을 명확하게 나누어 유지보수 하기 쉽게 하기 위함!
생명주기 콜백의 변화
초기화 작업
및 종료 작업
을 하기 위한 방법은 3가지가 있다.
- 인터페이스 상속
- 빈(Bean) 등록 초기화, 소멸 메서드
- 어노테이션
@PostConstruct
/@PreDestroy
1. 인터페이스 상속(InitializingBean, DisposableBean)
package hello.core.lifecycle;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class NetworkClient implements InitializingBean, DisposableBean {
//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 //InitializingBean에서 상속 받은 메서드, 빈 사용 준비가 완료 된 후 실행 됨
public void afterPropertiesSet() throws Exception {
connect();
call("초기화 연결 메시지");
}
@Override //DisposableBean에서 상속 받은 메서드, 빈 종료 전에 실행 됨
public void destroy() throws Exception {
disConnect();
}
}
InitializingBean
은afterPropertiesSet()
메서드로 초기화를 지원한다. → 빈 사용 준비가 완료 된후 실행되는 메서드DisposableBean
은destroy()
메서드로 소멸을 지원한다. → 빈 소멸 준비가 완료된 후에 실행되는 메서드
단점
- 스프링 전용 인터페이스에 의존
- 초기화, 소멸 메서드의 이름을 변경할 수 없음
- 개발자가 코드를 건드릴 수 없는 외부 라이브러리에 적용이 불가능
2. 빈(Bean) 등록 초기화, 소멸 메서드
- 빈 설정 정보에
@Bean(initMethod = “init", destroyMethod = “close”)
처럼 초기화, 소멸 메서드를 지정 한다. - 초기화 메서드 :
init
, 소멸 메서드 :close
로 지정
@Configuration
static class LifeCycleConfig {
@Bean(initMethod = "init", destroyMethod = "close")
public NetworkClient networkClient() {
NetworkClient networkClient = new NetworkClient();
networkClient.setUrl("http://hello-spring.dev");
return networkClient;
}
}
- 메서드 구현
package hello.core.lifecycle;
public class NetworkClient {
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);
}
public void init() { //init메서드
System.out.println("NetworkClient.init");
connect();
call("초기화 연결 메시지");
}
public void close() { //close메서드
System.out.println("NetworkClient.close");
disConnect();
}
설정 정보 사용 특징
- 메서드 이름을 자유롭게 설정 가능
- 스프링 빈이 스프링 코드에 의존X
- 코드를 고칠 수 없는 외부 라이브러리에도 초기화, 종료 메서드를 적용 가능
종료메서드의 특별한 기능
destroyMethod
는 기본값이inferred
(추론) 으로 등록되어 있다.destroyMethod
는 명시하지 않을때,close / shutdown
이름의 종료메서드를 기본적으로 추론하여 사용
→ 대부분 라이브러리에서 close 또는 shutdown 이름으로 사용- 추론기능을 사용하지 않을 경우
detroyMethod=””
으로 빈 공백을 지정
3. @PostConstruct, @PreDestroy 애노테이션의 사용
@PostConstruct
public void init() throws Exception {
System.out.println("NetworkClient.init");
connect();
call("초기화 연결 메세지");
}
@PreDestroy
public void close() throws Exception {
System.out.println("NetworkClient.close");
disconnect();
}
@PostConstruct
: 초기화 작업을 하는 메서드 위에 선언@PreDestroy
: 종료작업을 하는 메서드 위에 선언
- 최신 스프링에서 가장 권장하는 방법
- 외부 라이브러리에는 적용 불가 → @Bean의 기능을 사용해야 한다.
정리
@PostConstruct, @PreDestroy
애노테이션을 사용 할 것.- 외부 라이브러리를 초기화, 종료 해야할 시
@Bean
의 initMethod / destroyMethod 를 이용
반응형