6장 빈 라이프사이클과 범위
6-1. 컨테이너 초기화와 종료
// 1. 컨테이너 초기화
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppContext.class);
// 2. 컨테이너 -> 빈 객체 구해 사용
Greeter g = ctx.getBean("greeter", Greeter.class);
String msg = g.greet("스프링");
System.out.println(msg);
// 3. 컨테이너 종료
ctx.close();
- 컨테이너 초기화 : Bean 객체 생성, 의존 주입, 초기화
- 컨테이너 종료 : 빈 객체의 소멸
6-2. 스프링 빈 객체의 라이프사이클
- Bean 객체 생성
- 의존 설정 : 이 때, 의존 자동 주입이 수행됨
- 초기화 : Bean 객체 초기화
- 소멸 : Bean 객체 소멸
6-2-1. Bean 초기화, 소멸
- 초기화
public interface InitializingBean{
void afterPropertiesSet() throws Exception;
}
→ Bean 객체가 InitializingBean를 구현하면 초기화 과정에서 afterPropertiesSet() 메서드를 실행
- 소멸
public interface DisposableBean{
void destroy() throws Exception;
}
- Bean 객체가 DisposableBean를 구현하면 초기화 과정에서 destroy() 메서드를 실행
예시)
- main
public static void main(String[] args) throws IOException {
AbstractApplicationContext ctx =
new AnnotationConfigApplicationContext(AppCtx.class);
Client client = ctx.getBean(Client.class);
client.send();
ctx.close();
}
- AppCtx
@Configuration
public class AppCtx {
@Bean
public Client client() {
Client client = new Client();
client.setHost("host");
return client;
}
}
- Client
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() 실행");
}
public void send() {
System.out.println("Client.send() to " + host);
}
@Override
public void destroy() throws Exception {
System.out.println("Client.destroy() 실행");
}
}
- 결과
Client.afterPropertiesSet() 실행
Client.send() to host
17:59:47.532 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@10dba097, started on Thu May 19 17:59:47 KST 2022
Client.destroy() 실행
6-2-2. Bean 객체의 초기화와 소멸 : 커스텀 메서드
- 모든 클래스가 InitializingBean, DisposableBean 을 상속받아 구현할 수 있는것이 아님
- 외부에서 제공받은 클래스를 스프링 빈 객체로 설정하는 경우 → 직접 메서드를 지정할 수 있다.
- Client2 추가
public class Client2 {
private String host;
public void setHost(String host) {
this.host = host;
}
public void connect() {
System.out.println("Client2.connect() 실행");
}
public void send() {
System.out.println("Client2.send() to " + host);
}
public void close() {
System.out.println("Client2.close() 실행");
}
}
- AppCtx
@Configuration
public class AppCtx {
@Bean
public Client client() {
Client client = new Client();
client.setHost("host");
return client;
}
**@Bean(initMethod = "connect", destroyMethod = "close") // 직접 지정할 수 있다**
public Client2 client2() {
Client2 client = new Client2();
client.setHost("host");
return client;
}
}
- 실행 결과
Client.afterPropertiesSet() 실행
18:06:36.496 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'client2'
Client2.connect() 실행
Client.send() to host
18:06:36.554 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@10dba097, started on Thu May 19 18:06:36 KST 2022
Client2.close() 실행
Client.destroy() 실행
→ 설정 클래스는 자바 코드이므로, initMethod, destroyMethod 속성을 빈 설정 메서드에서 직접 초기화를 수행해도 된다.
@Bean(initMethod = "connect")
@Scope("singleton")
public Client2 client2() {
Client2 client = new Client2();
client.setHost("host");
return client;
}
- 주의사항
- initMethod, destroyMethod 속성에 지정한 메서드는 파라미터가 없어야 한다.
- 초기화 메서드가 두 번 불리지 않도록 한다.
6-3. Bean 객체의 생성과 관리 범위
1. 싱글톤
Client client1 = ctx.getBean(Client.class);
Client client2 = ctx.getBean(Client.class);
// client1 == client2 -> true
2. 프로토타입
- 빈 등록 시, @Scope를 prototype 으로 지정한다.
@Bean
@Scope("prototype")
public Client client() {
Client client = new Client();
client.setHost("host");
return client;
}
Client client1 = ctx.getBean(Client.class);
Client client2 = ctx.getBean(Client.class);
// client1 == client2 -> false
- 매번 새로운 객체를 생성
- default는 singleton 이다.
2-1. 프로토타입 주의사항
- 빈의 완전한 라이프사이클을 따르지 않는다.
- 컨테이너 종료 후 Bean 객체의 소멸 메서드를 실행하지 않는다.
- Bean 객체의 소멸 처리를 코드에서 직접 해야한다.
'공부 > Spring' 카테고리의 다른 글
[chap8] DB연동 (0) | 2022.05.27 |
---|---|
[chap7] AOP 프로그래밍 (0) | 2022.05.20 |
[chap5] 컴포넌트 스캔 (0) | 2022.05.20 |
[chap4] 의존 자동 주입 (0) | 2022.05.20 |
[chap3] 스프링 DI (0) | 2022.05.20 |
댓글