컨테이너 초기화와 종료
스프링 컨테이너는 초기화, 종료 라이프사이클을 갖고 있습니다.
컨테이너 초기화
AnnotationConfigApplicationContext ctx =
new AnnotationConfigApplicationContext(AppContext.class);
위 예제를 보면, AnnotationConfigApplicationContext 생성자를 이용해서 컨텍스트 객체를 생성하는데 이 시점에 스프링 컨테이너를 초기화합니다.
컨테이너에서 빈 객체 구하고 사용
Greeter g = ctx.getBean("greeter", Greeter.class);
String msg = g.greet("스프링");
System.out.println(msg);
스프링 컨테이너는 설정 클래스에서 정보를 읽어와 알맞은 빈 객체를 생성하고 각 빈을 연결(의존 주입)하는 작업을 수행합니다.
컨테이너 초기화가 완료되면 컨테이너를 사용할 수 있는데, 컨테이너를 사용한다는 것은 getBean()와 같은 메소드를 이용해서 컨테이너에 보관된 빈 객체를 구한다는 뜻입니다.
컨테이너 종료
ctx.close();
컨테이너 사용이 끝나면 컨테이너를 종료합니다. 이때, 사용하는 메서드가 close() 메소드입니다.
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext, DisposableBean {
// ...
@Override
public void close() {
close(null);
}
protected void close(@Nullable Throwable ex) {
synchronized (this.startupShutdownMonitor) {
doClose();
// ...
}
}
protected void doClose() {
// ...
destroyBeans();
closeBeanFactory();
// ...
}
protected void destroyBeans() {
getBeanFactory().destroySingletons();
}
protected void closeBeanFactory() {
if (this.beanFactory instanceof ConfigurableBeanFactory) {
((ConfigurableBeanFactory) this.beanFactory).destroySingletons();
}
}
// ...
}
close() 메소드는 AbstractApplicationContext에 정의되어있으며, 자바 설정을 사용하는 AnnotationConfigApplicationContext 클래스나 XML 설정을 사용하는 GenericXmlApplicationContext 클래스가 모두 AbstractApplicationContext를 상속받고 있습니다. 따라서 앞서 코드처럼 close() 메소드를 이용해서 컨테이너를 종료할 수 있습니다.
컨테이너를 초기화 하고 종료할 때에는 수행하는 작업은 다음과 같습니다.
* 컨테이너 초기화 : 빈 객체의 생성, 의존 주입, 초기화
* 컨테이너 종료 : 빈 객체의 소멸
스프링 빈 객체의 라이프 사이클
1. 객체 생성
2. 의존 설정
3. 초기화
4. 소멸
빈 객체의 초기화와 소멸 : 스프링 인터페이스
스프링 컨테이너는 빈 객체를 초기화하고 소멸하기 위해 빈 객체의 지정한 메서드를 호출합니다.
public interface InitalizingBean {
void afterPropertiesSet() throws Exception;
}
public interface DisposableBean {
void destroy() throws Exception;
}
- org.springframework.beans.factory.InitalizingBean
- org.springframework.beans.factory.DisposableBean
[생성 - 초기화]
빈 객체가 InitalizingBean 인터페이스를 구현하면 스프링 컨테이너는 초기화 과정에서 빈 객체의 afterPropertiesSet() 메서드를 실행합니다. 빈 객체를 생성한 뒤 초기화 과정이 필요하면 InitalizingBean 인터페이스를 상속하고 afterPropertiesSet()를 구현하면 됩니다.
[소멸]
빈 객체가 DisposableBean 인터페이스를 구현한 경우 소멸 과정에서 빈 객체의 destory() 메소드를 실행합니다. 빈 객체의 소멸 과정이 필요하면 DisposableBean 인터페이스를 상속하고 destory() 메소드를 구현하면 됩니다.
빈 객체의 초기화와 소멸 과정이 필요한 예로, 데이터베이스 커넥션 풀이 있습니다.
커넥션 풀을 위한 빈 객체는 초기화 과정에서 데이터베이스 연결을 생성합니다. 컨테이너를 사용하는 동안 연결을 유지하고 빈 객체를 소멸할 때 사용중인 데이터베이스 연결을 끊어야 합니다.
또한, 채팅 클라이언트는 시작할 때 서버와 연결을 생성하고 종료할 때 연결을 끊습니다. 이때 서버와의 연결을 생성하고 끊는 작업을 초기화 시점과 소멸 시점에 수행하면 됩니다.
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
public class Client implements InitializingBean, DisposableBean{
private String host;
public void setHost(String host) {
this.host = host;
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("Client.afterPropertiesSet 실행");
}
@Override
public void destroy() throws Exception {
System.out.println("Client.destroy 실행");
}
public void send() {
System.out.println("Client.send to" + host);
}
}
Client 클래스는 InitalizingBean과 DisposableBean을 상속받고 각각 afterPropertiesSet()과 destroy()를 구현하였습니다.
Client 클래스를 빈 객체로 등록하는 설정클래스는 다음과 같습니다.
@Configuration
public class AppCtx3 {
@Bean
public Client client() {
Client client = new Client();
client.setHost("host");
return client;
}
}
그러면, 메인에서는 스프링 컨테이너를 생성하고, Client 빈 객체를 구해 사용하게 됩니다.
public class Main {
public static void main(String[] args) {
//1. 컨테이너 초기화
AbstractApplicationContext ctx =
new AnnotationConfigApplicationContext(AppCtx3.class);
//2. 빈 객체 로드 후, 사용하기
Client client = ctx.getBean(Client.class);
client.send();
//3. 컨테이너 종료
ctx.close();
}
}
실행을 해보면 다음과 같습니다.
스프링 컨테이너는 빈 객체 생성을 마무리 한 뒤에 초기화 메서드 afterPropertiesSet()를 실행합니다.
그리고 스프링 컨테이너를 종료하면 destory()가 호출되는 것을 볼 수 있습니다.
만약, 주석 3의 컨테이너 종료 ctx.close()가 호출되지 않았다면, 컨테이너의 종료과정을 수행하지 않고, 빈 객체의 소멸 과정도 실행되지 않아, destory()가 실행되지 않습니다.
지금까지 빈 라이프사이클 초기화와 소멸 과정에서 스프링이 제공하는 인터페이스는 뭐가 있는지 알아보았습니다.
다음 포스팅은 초기화와 소멸 과정을 직접 구현하는 커스텀 메서드에 대해 알아보겠습니다.
감사합니다.
'Spring' 카테고리의 다른 글
[Spring] 빈 객체의 생성과 관리범위 (0) | 2024.01.29 |
---|---|
[Spring] 빈 라이프 사이클 - 빈 객체의 초기화와 소멸 : 커스텀 메소드 (0) | 2024.01.29 |
[Spring] AOP 프로그래밍이란 ? (1) | 2024.01.25 |
[Spring] Autowired 와 수동 Bean 등록 (@Qualifier) (0) | 2024.01.24 |
[Spring] @Autowired - 의존성 자동주입 (0) | 2024.01.24 |