빈 생명주기
스프링 빈은 다음과 같은 생명주기를 갖는다.
스프링 컨테이너 생성 -> 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 -> 사용 -> 소멸 전 콜백 -> 스프링 컨테이너 종료
여기서는 콜백에 대해서 알아보도록 하자.
초기화 콜백: 빈이 생성되고, 빈의 의존관계 주입이 완료된 이후에 호출
소멸 전 콜백: 빈이 소멸되기 직전에 호출
콜백이란?
1. 다른 함수의 인자로써 이용되는 함수
2. 어떤 이벤트에 의해 호출되어지는 함수
예를들어 케이블이 연결될 때 "케이블이 연결되었습니다"라는 메시지가 출력되는 프로그램이 있다고 하자.
function onCableConnected(){
print("케이블이 연결되었습니다");
};
//케이블이 연결될 때 마다 전달된 onCableConnected가 호출된다고 가정
setOnCableConnected(onCableConnected);
위와 같이 코드를 짤 수 있는데, 이때 케이블이 연결되었다는 이벤트가 발생했을때 onCableConnected()함수가 호출 되므로 콜백함수라고 말할 수 있다.
스프링에서의 콜백 지원 방법
1. 인터페이스(InitioalizingBean, DisposableBean)
public class ExampleCode implements InitializingBean, DisposableBean {
/**
* InitializingBean
* 의존관계 주입이 끝나면
*/
@Override
public void afterPropertiesSet() throws Exception {
// 초기화에 필요한 로직 구현
}
/**
* DisposableBean
* 빈이 소멸되기 전
*/
@Override
public void destroy() throws Exception {
// 빈소멸전 필요한 로직 구현
}
}
해당 인터페이스의 단점
- 스프링 전용 인터페이스이므로 해당 코드가 스프링 전용 인터페이스에 의존한다.
- @Override를 통해 구현하므로 메소드 이름을 변경 할 수 없다.
- 인터페이스에 메소드를 이용하므로 외부 라이브러리에는 적용 할 수 없다.
2. 빈 등록 초기화, 소멸 메소드 지정
public void init() {
//초기화 콜백
}
public void close() {
//소멸전 콜백
}
초기화 메소드 intit()과 소멸 메소드 close를 구현하였다.
@Configuration
static class LifeCycleConfig {
@Bean(initMethod = "init", destroyMethod = "close")
public ExampleCode exampleCode() {
ExampleCode exampleCode = new ExampleCode();
return exampleCode;
}
}
해당 @Bean 에 직접 메소드 이름으로 초기화메소드와 소멸 메소드를 지정할 수 있다.
설정 정보의 사용특징
- 메서드 이름을 자유롭게 줄 수 있다.
- 스프링 빈이 스프링 코드에 의존하지 않는다
- 외부 라이브러리에도 초기화, 종료 메서드를 적용 할 수 있다.
destroyMethod 의 특수기능
- destroyMethod는 기본값이 (inferred)추론으로 등록되어있다. 보통 라이브러리는 종료하는 메소드 이름이 close, shutdown 이라는 이름으로 종료 메서드를 사용한다. 그래서 destroyMethod을 따로 적어주지 않아도 추론해서 close, shutdown 메소드가 존재하면 자동으로 호출해준다.
- 해당 기능을 사용하고 싶지 않으면 destroyMethod="" 으로 공백으로 설정한다.
3. @PostConstruct, @PreDestroy
@PostConstruct
public void init() {
//초기화 콜백
}
@PreDestroy
public void close(){
//소멸전 콜백
}
어노테이션을 이용해 초기화와 종료를 실행할 수 있다.
가장 편리하게 사용할 수 있는 방법이다
스프링에서 가장 권장하는 방법이고 javax 패키지를 사용해 스프링에 종속적인 기술이 아니라 JSR-250의 자바 표준이라 스프링이 아닌 다른 컨테이너 에서도 동작한다.
단점
- 이것도 외부 라이브러리에 적용할 수 없다. 외부 라이브러리에 적용을 해야한다면 2번 @Bean에 설정하는 기능을 이용하자.
외부 라이브러리에 등록할 수 없다?
@Bean을 이용하면 코드가 아니라 설정 정보를 사용하기 때문에 코드를 고칠 수 없는 외부 라이브러리에도 적용할 수 있다.
예로 gradle로 들어보겠다. gradle은 우리가 수정할 수 없는 외부 라이브러리이다. 여기서 테스트를 한다고 했을 때, 우리는 테스트 코드를 짜면서 직접 @Bean으로 등록할 때, 해당 라이브러리에 있는 클래스 안에 있는 메소드들을 파악하고 빈으로 직접 등록하여 초기화, 종료를 할 수 있다.
그러나 어노테이션은 코드에 @을 붙여야하는데 코드를 수정할 수 없기 때문에 사용할 수 없다.
마찬가지로 @PostConstruct, @PreDestroy 애노테이션들은 코드가 수정 가능한 곳에 적용 가능하며
그렇지 못한 곳에서는 @Bean의 init method, destory method를 통해서 초기화, 종료 메서드를 지정할 수 있다.
'Spring' 카테고리의 다른 글
Servlet과 Spring MVC (0) | 2023.03.06 |
---|---|
AOP의 개념 (0) | 2023.02.05 |
Spring vs Spring boot (0) | 2022.11.09 |
Maven & Gradle (0) | 2022.11.08 |
BeanFactory & ApplicationContext (0) | 2022.11.08 |