빈 생명주기 콜백이라는게 모지?
그냥 내가 이해한 바로는 스프링이 구동될때 DB 연결이나 Network 연결은 미리 해주어야 나중에 연결 지연이 생기는 것이 방지 된다고 한다. 그래서 그때 동작되는 스프링이 구동되고서부터 끝날때까지의 흐름??
그리고 스프링이 구동되고 의존관계가 주입된 후에 어떤것이 호출되며 종료되기 전에는 어떤것이 호출되는지 그런흐름?? 모 나는 그렇게 이해했는데 아닐수도 ;;;
김영한님의 인프런 스프링 기본편강의 에서는 아래와 같은 흐름으로 동작한다고 하였다!
스프링 컨테이너 생성 → Bean 등록 → 의존관계주입 → 초기화콜백 → 사용 → 소멸전 콜백 → 스프링 종료
스프링은 크게 3가지 방법으로 빈 생명주기 콜백을 지원한다.
1. 인터페이스(InitializingBean, DisposableBean)
InitializingBean, DisposableBean 인터페이스를 상속받아 구현하기. afterPropertiesSet() 메서드는 의존관계 주입이 끝나면 바로 실행되며, destroy() 메서드는 스프링이 종료되기 전 실행된다.
따라서 해당 메소드 안에 샐행될때 connection 해주어야하는 코드와 종료될때 실행되어야 하는 코드를 넣어주면 된다.
public class NetworkClient implements InitializingBean, DisposableBean {
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 message) {
System.out.println("call: " + url + " message = " + message);
}
//서비스 종료시 호출
public void disConnect() {
System.out.println("close + " + url);
}
@Override
public void afterPropertiesSet() throws Exception {
connect();
call("초기화 연결 메시지");
}
@Override
public void destroy() throws Exception {
disConnect();
}
}
단점❗
해당 인터페이스는 스프링 전용 인터페이스로 해당 코드가 스프링 전용 인터페이스에 의존한다. 또한 초기화, 소멸 메서드의 이름을 변경할 수 없으며, 내가 코드를 고칠 수 없는 외부 라이브러리에 적용할 수 없다! 그냥 되도록 사용하지 말라는말❗❗❗
2. @Bean(initMethod = “init”, destroyMethod = “close”)
설정 정보에 @Bean(initMethod = “init”, destroyMethod = “close”) 처럼 초기화, 소멸 메서드를 지정할 수 있다.
@Configuration
static class LifeCycleConfig {
@Bean(initMethod = "init", destroyMethod = "close")
public NetworkClient networkClient() {
NetworkClient networkClient = new NetworkClient();
networkClient.setUrl("<http://hello-spring.dev>");
return networkClient;
}
}
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 message) {
System.out.println("call: " + url + " message = " + message);
}
//서비스 종료시 호출
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();
}
}
✅ 장점이자 특징
- 메서드 이름을 자유롭게 줄 수 있다.
- 스프링 빈이 스프링 코드에 의존하지 않는다.
- 코드가 아니라 설정 정보를 사용하기 때문에 코드를 고칠 수 없는 외부 라이브러리에도 초기화, 종료 메서드를 적용할 수 있다.
- 또한, destroyMethod 는 기본값으로 close, shutdown 이 있기에 아예 안써주거나 destroyMethod=”” 처럼 빈 공백을 지정해도 된다.
3. @PostConstruct, @PreDestroy
그냥 초기화 값에 @PostConstruct, 종료값에 @PreDestroy 어노테이션을 붙이는 간편한 방식이다.
@Configuration
static class LifeCycleConfig {
@Bean
public NetworkClient networkClient() {
NetworkClient networkClient = new NetworkClient();
networkClient.setUrl("<http://hello-spring.dev>");
return networkClient;
}
}
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 message) {
System.out.println("call: " + url + " message = " + message);
}
//서비스 종료시 호출
public void disConnect() {
System.out.println("close + " + url);
}
@PostConstructv // ✅ 요기!!
public void init() {
System.out.println("NetworkClient.init");
connect();
call("초기화 연결 메시지");
}
@PreDestroy // ✅ 요기!!
public void close() {
System.out.println("NetworkClient.close");
disConnect();
}
}
✅ 장점 및 특징
- 최신 스프링에서 가장 권장하는 방식
- 어노테이션 하나만 붙이면 되므로 매우 간편
- 스프링에 종속된 기술이아니여서 스프링이 아닌 다른 컨테이너에서도 동작한다. (package 에 javax.~~~ 로 되어 있는것들은 자바표준 이라는 뜻.)
유일한 단점❗
외부 라이브러리에 적용하지 못한다.
참고
인프런 - 김영한의 스프링 기본편
'Spring' 카테고리의 다른 글
빈 스코프와 종류 (0) | 2022.07.03 |
---|---|
Thread Pool 이란 도대체 무엇인가! (0) | 2022.06.17 |
조회 빈이 2개 이상일 때 해결방법! (0) | 2022.06.04 |
[Springboot] Execution failed for task ':test' 에러 해결방법 (0) | 2022.06.04 |
의존관계가 아닐때 옵셔널처리 (0) | 2022.06.04 |
댓글