객체 생성 → 의존관계 주입
스프링 빈은 객체 생성, 의존관계 주입이 끝나야 필요한 데이터를 사용할 수 있음, 객체의 데이터 초기화는 의존관계 주입이 끝난 뒤에 가능
콜백을 통해서 초기화 시점과 종료 시점을 알려줌
1) 스프링 컨테이너 생성
2) 스프링 빈 생성
3) 의존관계 주입
4) 초기화 콜백
5) 빈 사용
6) 소멸 전 콜백
7) 스프링 종료
객체의 생성과 초기화를 분리
생성자는 객체 생성을 위한 정보를 받고, 메모리에 객체를 생성하는 역할
초기화는 생성된 객체를 활용하여 외부와 커넥션을 연결하는 무거운 동작을 수행
=> 생성자 안에서 무거운 초기화 작업을 하지 않고, 객체를 생성하는 부분과 초기화하는 부분을 분리(별도의 초기화 메서드)
스프링의 콜백 지원
1) InitializingBean, DisposableBean 인터페이스 => 사용 X
- 스프링 전용 인터페이스라서, 스프링에 의존적임
- 인터페이스의 메서드를 오버 라이딩하기 때문에, 초기화/소멸 메서드의 이름 변경 불가
- 코드 수정이 불가능한 외부 라이브러리에 적용 불가
2) 설정 정보에 초기화/소멸 메서드 지정 => 외부 라이브러리 연동에 사용
- @Bean(initMethod = "init", destroyMethod = "close")
public class NetworkClient {
private String url;
public NetworkClient() {
System.out.println("생성자 url : " + url);
}
public void setUrl(String url) {
this.url = url;
}
public void connect() {
System.out.println("connect : " + url);
}
public void call(String msg) {
System.out.println("call = " + url + " / msg = " + msg);
}
public void disConnect() {
System.out.println("close = " + url);
}
// 초기화 메서드
public void init() {
System.out.println("NetworkClient.init");
connect();
call("메시지~~~~");
}
// 소멸 메서드
public void close() {
System.out.println("NetworkClient.close");
disConnect();
}
}
public class LifeCycleTest {
@Test
public void lifeCycleTest() {
AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);
ac.close();
}
@Configuration
static class LifeCycleConfig {
@Bean(initMethod = "init", destroyMethod = "close")
public NetworkClient networkClient() {
NetworkClient nc = new NetworkClient();
nc.setUrl("http://hello.com");
return nc;
}
}
}
생성자 url : null
NetworkClient.init
connect : http://hello.com
call = http://hello.com / msg = 메시지~~~~
16:19:33.041 [main] DEBUG org.springframework.context.annotation.AnnotationConfigApplicationContext - Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@45018215, started on Sun Apr 18 16:19:32 KST 2021
NetworkClient.close
close = http://hello.com
설정 클래스 LifeCycleConfig를 보고 객체 생성 → 의존관계 주입 → 초기화 콜백 메서드(init메서드) → 사용 → 소멸 콜백 메서드(close메서드) → 종료(ac.close())
- 초기화/소멸 메서드 이름을 맘대로 할 수 있음
- 스프링에 의존 X
- 설정 정보의 @Bean에 지정하기 때문에 외부 라이브러리에도 적용이 가능
- destroyMethod이름을 따로 지정하지 않으면 close나 shutdown이라는 메서드를 호출함 (기본값이 추론 / inferred)
(라이브러리의 종료 메서드는 대부분 close나 shutdown)
3) @PostConstruct, @PreDestroy 어노테이션 => 사용 권장
- 초기화 메서드에 @PostConstruct
- 소멸 메서드에 @PreDestroy
public class NetworkClient {
private String url;
public NetworkClient() {
System.out.println("생성자 url : " + url);
}
public void setUrl(String url) {
this.url = url;
}
public void connect() {
System.out.println("connect : " + url);
}
public void call(String msg) {
System.out.println("call = " + url + " / msg = " + msg);
}
public void disConnect() {
System.out.println("close = " + url);
}
// 초기화 메서드
@PostConstruct
public void init() {
System.out.println("NetworkClient.init");
connect();
call("메시지~~~~");
}
// 소멸 메서드
@PreDestory
public void close() {
System.out.println("NetworkClient.close");
disConnect();
}
}
- 어노테이션만 붙이면 돼서 간편함
- @PostConstruct, @PreDestroy는 스프링에 종속된 것이 아니고 자바 표준임
- @Bean을 사용하지 않기 때문에 컴포넌트 스캔과 잘 어울림
- 단점은 설정 클래스에 작성하는 것이 아니라 외부 라이브러리에는 적용을 못함
정리
- 초기화/소멸 메서드 지정을 위해서 @PostConstruct, @PreDestroy를 사용
- 외부 라이브러리에 적용해야 할 때는 @Bean의 initMethod, destroyMethod를 사용
'WEB > spring' 카테고리의 다른 글
[Spring] 스프링 부트 로깅, slf4j, logback (0) | 2021.05.30 |
---|---|
[Spring] Spring MVC구조, Spring 동작원리, DispatherServlet (0) | 2021.05.30 |
[Spring] 자동 빈 등록(@Component) vs 수동 빈 등록(@Bean) (0) | 2021.04.18 |
[Spring] @AutoWired 조회 빈 2개 이상, @Qualifier, @Primary (0) | 2021.04.18 |
[Spring] 의존관계 주입 방법(생성자/수정자/필드/메서드 주입) (0) | 2021.04.17 |