컨테이너 초기화와 종료
스프링 컨테이너는 초기화, 종료 라는 라이프 사이클을 갖는다.
1
2
3
4
5
6
7
8
|
// 스프링 컨테이너 초기화
// 스프링 컨테이너는 설정 클래스에서 정보를 읽어와 알맞은 빈 객체를 생성하고
// 의존 주입 하는 작업을 수행한다.
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppCtx.class);
// 초기화된 컨테이너를 사용한다 - 메서드를 이용해 컨터이너에 보관된 빈 객체를 구한다.
Greeting greeting = context.getBean("greeting", Greeting.class);
// 컨테이너를 종료한다.
context.close();
|
cs |
위 예시에서 close() 메서드는 AbstractApplicationContext 클래스에 정의되 있다. 자바 설정을 사용하는 AnnotationConfigApplicationContext와 XML 설정을 사용하는 GenerixXmlApplicationContext는 모두 AbstarctApplicationContext를 상속받는다.
컨테이너의 초기화, 종료는 다음과 같은 작업도 동반한다.
컨테이너 초기화 - 빈 객체의 생성, 의존 주입, 초기화
컨테이너 종료 - 빈 객체의 소멸
스프링 빈 객체의 라이프사이클
스프링 컨테이너는 빈 객체의 라이프사이클을 관리한다. 빈 객체의 라이프사이클은 다음과 같다.
객체 생성 -> 의존 설정 -> 초기화 -> 소멸
스프링 컨테이너를 초기화하면 빈 객체를 생성하고 의존성을 주입한다. 의존 자동 주입을 통한 의존 설정이 이 시점에 수행된다. 그 후 빈 객체의 초기화를 수행한다. 이를 위해 스프링은 빈 객체의 지정된 메서드를 호출한다. 스프링 컨테이너 종료 시 컨테이너가 빈 객체의 소멸을 처리하는데, 이 때 역시 지정한 메서드를 처리한다.
빈 객체의 초기화와 소멸: 스프링 인터페이스
빈 객체를 초기화 하거나 소멸하기할 때 특정 로직을 수행해야 한다면 다음과 같은 두 개의 인터페이스를 implements 하면 된다.
1
2
3
4
5
6
7
8
9
|
// org.springframework.beans.factory.initializingBean
public interface InitializingBean {
void afterPropertiesSet() throws Exception;
}
// org.springframework.beans.factory.DisposableBean
public interface DisposableBean {
void destroy() throws Exception;
}
|
cs |
InitializingBean 인터페이스를 구현하면 스프링 컨테이너 초기화 과정에서 빈 객체의 afterPropertiesSet() 메서드를 실행한다. DisposaableBean 인터페이스를 구현했다면 소멸과정에서 destroy() 메서드를 실행한다.
이런 동작은 DB 연결 등에 필요하다. DB 커넥션 풀을 위한 빈 객체는 초기화 과정에서 DB 연결을 생성하고 빈 객체가 소멸하면 DB 연결을 끊어야 한다. 이 때 InitializingBean과 DisposableBean 인터페이스를 사용하면 된다.
빈 객체의 초기화와 소멸: 커스텀 메서드
외부에서 제공받은 클래스는 InitializingBean과 DisposableBean 인터페이스를 implements할 수 없다. 이럴때는 스프링 설정에서 직접 메서드를 지정할 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public class Bean {
public void connect() {
}
public void printHello() {
System.out.println("hello");
}
public void close(){
}
}
// 위와 같은 클래스가 존재하고
// connect()를 초기화 과정에서, close()를 소멸 과정에서 사용하고 싶다면
// 아래와 같이 @Bean 어노테이션에 속성을 지정하면 된다.
@Bean(initMethod = "connect", destroyMethod = "close")
public setter.Bean bean() {
return new setter.Bean();
}
|
cs |
connect() 메서드와 close() 메서드는 private 이여도 상관없다. 또 한, initMethod, destroyMethod 속성에 지정한 메서드는 파라미터가 없어야 한다. 있다면 스프링 컨테이너는 다음과 같은 에러를 발생시킨다.
1
2
|
Invocation of init method failed; nested exception is
org.springframework.beans.factory.support.BeanDefinitionValidationException
|
cs |
initMethod 속성을 지정하고 싶지 않다면, 다음과 같이 사용해 initMethod 속성을 사용하지 않을 수 있다.
1
2
3
4
5
6
|
@Bean(destroyMethod = "close")
public setter.Bean bean() {
setter.Bean bean = new setter.Bean();
bean.connect();
return bean;
}
|
cs |
빈 객체의 생성과 관리 범위
스프링의 빈은 기본적으로 싱글톤 스코프이다. 즉, 한 식별자에 대해 한 개의 객체만 존재한다. 이 스코프를 프로토타입으로 지정한다면 빈 객체를 구할 때마다 매번 새로운 객체를 생성한다. 스코프의 지정은 @Scope 어노테이션으로 할 수 있다.
1
2
3
4
5
6
7
8
|
// prototy scope으로 지정
@Bean
@Scope("prototype")
public setter.Bean bean() {
setter.Bean bean = new setter.Bean();
bean.connect();
return bean;
}
|
cs |
빈이 프로토타입 스코프를 갖는다면 완전한 라이프사이클을 따르지 않는다. 프로토타입 스코프의 빈은 컨테이너 생성 시 빈 객체가 생성되고 설정을 초기화 하는 과정 까지는 싱글톤 스코프 빈과 동일하다. 하지만 컨테이너 종료 시 빈 객체가 소멸되지 않는다. 따라서 컨테이너 종료시 명시적으로 소멸처리 해야 한다.
출처 - 초보 웹 개발자를 위한 스프링 5 프로그래밍 입문
'도서 > 초보 웹 개발자를 위한 스프링 5 프로그래밍 입문' 카테고리의 다른 글
Chapter10. 스프링 MVC 프레임워크 동작 방식 (0) | 2022.08.21 |
---|---|
Chapter 8. DB 연동 (0) | 2022.05.24 |
Chapter 5. 컴포넌트 스캔 (0) | 2022.05.02 |
Chapter 4. 의존 자동 주입 (0) | 2022.05.02 |
Chapter 03. Spring DI(Dependency Injection) (0) | 2022.04.25 |