티스토리 뷰
데이터베이스 커넥션 풀을 연결할 때. 혹은 소켓을 연결할 때. 객체 생성 이후 연결을 맺고, 객체가 사라지기 전에 연결을 끊는 작업이 필요하다. 스프링에서는 이런 초기화 작업, cleanup 작업을 쉽게 할 수 있도록 기능을 제공한다.
먼저 스프링 빈의 라이프사이클은 다음과 같다.
스프링 컨테이너 생성 -> 스프링 빈 생성 -> 의존관계 주입 -> 초기화 콜백 -> ... -> 소멸전 콜백 -> 스프링 종료
스프링에서는 초기화 콜백, 소멸전 콜백을 구현할 수 있는 세가지 방법을 제공한다.
spring 인터페이스를 활용하는 방법, @Bean 기능을 이용하는 방법, 또 다른 annotation을 활용하는 방법이다.
차례대로 알아보자.
1. 인터페이스 InitializingBean, DisposableBean
InitializeBean, DisposableBean을 implements 한 뒤, afterPropertiesSet() 과 disconnect()를 override하는 방법이다.
스프링 인터페이스에 의존적이고, 메소드 명을 바꿀 수 없으며 외부 라이브러리에 적용할 수 없다는 단점이 있다. 잘 쓰이지 않는 방법이다.
2. @Bean 기능
@Bean을 이용해 bean을 수동 등록하고, 이때 @Bean(initMethod = "init", destroyMethod = "close") 와 같이 initMethod와 destroyMethod 각각에 초기화 하는 함수와 cleanup 함수를 넣어 준다. 물론 초기화 함수와 cleanup 함수가 객체 내에 정의되어 있어야 한다.
public class NetworkClient {
private String url;
public NetworkClient() {
System.out.println("생성자 호출, url = " + url);
//connect();
//call("초기화 연결 메시지");
}
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.afterPropertiesSet");
connect();
call("초기화 연결 메시지");
}
public void close(){
System.out.println("NetworkClient.destroy");
disconnect(); //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;
}
}
위와 같이 사용하면 된다.
추가적으로, destroyMethod를 명시하지 않으면 스프링에서 "shutdown", "close"라고 되어있는 메소드를 찾아서 자동으로 cleanup 함수로 호출한다. 만약 cleanup 함수를 호출하고 싶지 않다면 destroyMethod="" 라고 명시하자.
3. @PostConstruct, @PreDestory
어노테이션 이름을 보면 알 수 있듯이, 초기화 함수에 @PostConstruct를(생성자 이후 실행된다는 의미다), cleanup 함수에 @PreDestroy를 붙이면 된다. (매우 편리하다!)
public class NetworkClient {
private String url;
public NetworkClient() {
System.out.println("생성자 호출, url = " + url);
//connect();
//call("초기화 연결 메시지");
}
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.afterPropertiesSet");
connect();
call("초기화 연결 메시지");
}
@PreDestroy
public void close(){
System.out.println("NetworkClient.destroy");
disconnect(); //close를 안전하게
}
}
현재 스프링에서 권장하는 방법이고, 가장 일반적으로 쓰이는 방식이다. bean 자동 등록(컴포넌트 스캔)과 잘 어울린다.
단점이 하나 있는데, 외부 라이브러리에 적용이 어렵다는 점이다. 외부 라이브러리 객체를 스프링 빈으로 등록해서 쓴다면, 외부 라이브러리 코드를 수정할 수 없기 때문에 이 방법으로 초기화, cleanup 함수를 지정할 수 없다. 이때는 위에서 이야기한 @Bean 기능을 이용하자. (외부 라이브러리에서 보통 초기화, cleanup 함수가 정의되어 있으므로 이를 initMethod와 destroyMethod로 지정하면 된다)
사진, 내용 출처 : 인프런, 김영한 강사님의 '스프링 핵심 원리 - 기본편' 강좌, 강의자료
'SPRING' 카테고리의 다른 글
request 스코프(feat. Provider, Proxy) (0) | 2021.05.21 |
---|---|
프로토타입 스코프 (0) | 2021.05.20 |
Map, List를 활용해 모든 빈 조회하기 (0) | 2021.05.18 |
의존관계 주입 시 스프링 빈이 2개 이상 조회될 때 (feat. @Qualifier, @Primary) (0) | 2021.05.18 |
의존관계 주입 방법 (0) | 2021.05.17 |
- Total
- Today
- Yesterday
- java
- 디자인패턴
- gracefulshutdown
- 예외처리
- 프록시
- AOP
- provider
- 토비의스프링
- 백기선
- 코테
- 토비의봄TV
- BOJ
- 카카오
- 자바
- 김영한
- OOP
- 데코레이터패턴
- 프록시패턴
- 토비
- ec2
- 서비스추상화
- 객체지향
- 자바스터디
- 프로그래머스
- c++
- 메서드레퍼런스
- 템플릿콜백
- 코딩테스트
- 스프링
- SOLID
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |