티스토리 뷰

데이터베이스 커넥션 풀을 연결할 때. 혹은 소켓을 연결할 때. 객체 생성 이후 연결을 맺고, 객체가 사라지기 전에 연결을 끊는 작업이 필요하다. 스프링에서는 이런 초기화 작업, 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로 지정하면 된다)

 

사진, 내용 출처 : 인프런, 김영한 강사님의 '스프링 핵심 원리 - 기본편' 강좌, 강의자료

https://inf.run/TErf

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2024/12   »
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
글 보관함