💋 빈 생명주기 콜백
스프링에서 빈을 최초에 생성하는 작업을 크게 본다면 '생성'이라고 할 수 있겠지만, 상세히 구분한다면 생성과 초기화 작업으로 나눌 수 있다.
생성자를 통해서 내부 값들을 설정하는 가벼운 작업의 경우에 생성자에서 처리하는 것이 좋겠지만, 초기화 작업이 무거워지는 경우도 존재한다. 예를 들면.. 데이터베이스 커넥션 풀 관련해서 애플리케이션 시작 시점에 모든 연결을 하고, 종료 시점에 모든 연결을 종료하는 작업이 있다. 이런 무거운 작업의 경우에는 객체 생성과 초기화에 대한 부분을 완전히 분리하는 것이 좋을 때도 있다.
객체의 초기화와 종료를 위한 별도의 작업이 필요한 경우에 콜백 메서드를 사용할 수 있다.
스프링은 의존 관계 주입이 완료되면, 초기화 콜백 메서드를 통해서 초기화 작업을 수행하고,
스프링 컨테이너가 종료되기 전에 소멸 콜백 메서드를 통해서 종료 작업을 수행한다.
이 두 가지를 묶어서 빈 생명주기 콜백이라고 부른다.
스프링에서 빈 생명주기 콜백을 사용하는 방법은 크게 세 가지로 분류할 수 있다.
- 인터페이스(InitializingBean, DisposableBean)
- 설정 파일에서 초기화, 종료에 대한 메서드를 직접 설정
- 어노테이션(@PostConstruct, @PreDestroy)
각 방법에 대해 예시와 함께 설명하겠다!
✔ 인터페이스(InitializingBean, DisposableBean)
@Component
public class DataConnectionClient implements InitializingBean, DisposableBean {
@Override
public void afterPropertiesSet() throws Exception {
// 의존관계 주입이 끝난 후에 실행할 코드
System.out.println("의존관계 주입이 끝난 후에 실행할 코드");
}
@Override
public void destroy() throws Exception {
// 스프링 컨테이너 소멸 직전에 실행할 코드
System.out.println("스프링 컨테이너 소멸 직전에 실행할 코드");
}
}
DataConnectionClient 빈이 생성되는 시점에서 afterPropertiesSet()이 실행되고, 애플리케이션이 종료되면서 스프링 컨테이너가 소멸하기 직전에 destroy() 메서드가 실행되는 것을 확인할 수 있다.
해당 방법은 단점도 있다.
1. 코드가 스프링 코드에 너무너무 의존적...!
2. 메서드 이름을 변경할 수가 없음
3. 내가 코드를 고칠 수 없는 외부 라이브러리에 적용할 수 없다.
(초창기에 나온 방법이라 지금은 거의 사용하지 않음)
✔ 설정 파일에서 초기화, 종료에 대한 메서드를 직접 설정
@Configuration
class LifeCycleConfig {
@Bean(initMethod = "init", destroyMethod = "close")
public DataConnectionClient dataConnectionClient() {
final DataConnectionClient dataConnectionClient = new DataConnectionClient();
dataConnectionClient.setUrl("http://gitchan.dev");
return dataConnectionClient;
}
}
위 코드와 같이 초기화와 소멸 콜백 메서드를 직접 "init", "close"로 지정해줄 수 있다.
1. 이름을 직접 지정할 수 있다.
2. 스프링 빈이 스프링 코드에 의존하지 않는다.
3. 설정 정보를 사용하기 때문에 외부 라이브러리를 사용하는 경우에도, 내가 사용할 코드를 수정하면 초기화, 소멸 메서드를 지정할 수 있다.
✔ 어노테이션(@PostConstruct, @PreDestroy)
이 방법이 가장 편하고, 쉽다! (추천함)
@PostConstruct
public void init() {
connect();
call("초기화 연결 메시지");
}
@PreDestroy
public void close() {
disConnect();
}
빈으로 등록된 객체에서 위와 같이 어노테이션과 함께 콜백 메서드를 작성해주면 된다!
1. 스프링에 종속적인 기술이 아니라 JSR-250 라는 자바 표준 어노테이션이기 때문에, 다른 컨테이너에서도 동작한다.
2. 외부 라이브러리에는 적용하지 못한다.
외부 라이브러리를 초기화, 종료 해야 하면 @Bean의 기능을 사용해서 2번째 방법을 사용하는 것이 좋다!