개요

데이터베이스 커넥션 풀 혹은 웹소켓처럼 애플리케이션이 시작될 때 연결하고 애플리케이션이 종료 될 때 연결이 모두 종료되는 작업을 진행하기 위해서는 객체의 초기화 작업이 필요함. 여기서 말하는 객체의 초기화 작업은 생성자혹은 파라미터로 받은 값들을 활용해 외부 커넥션을 연결하는 무거운 작업 등을 말한다. 예를 들어 실제로 데이터베이스, Redis, 웹소켓 등의 연결을의미한다. 

 

예시

임의의 DatabaseClient 클래스를 하나 만든다. 실제로 DB 에 접근하는게 아닌 빈의 생명주기를 보기위해 정의한 것.

package hello.core.lifecycle;

public class DatabaseClient {

    private String url;
    private int port;

    public DatabaseClient() {
        System.out.println("생성자 호출, " + port + url);
        connect();
        call("초기화 연결 메세지");
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public void setPort(int port) {
        this.port = port;
    }

    // 시작시 호출
    public void connect() {
        System.out.println("connect: " + url + " port: " + port);
    }

    public void call(String message) {
        System.out.println("call: " + url + " port: " + port + " message = " + message );
    }

    // 종료시 호출
    public void disconnect() {
        System.out.println("close: " + url + port);
    }

}

그리고 테스트 코드를 작성한다.

package hello.core.lifecycle;

import org.junit.jupiter.api.Test;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

public class BeanLifeCycleTest {

    @Test
    public void lifeCycleTest() {
        ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);
        DatabaseClient client = ac.getBean(DatabaseClient.class);
        ac.close();
    }


    @Configuration
    static class LifeCycleConfig {
        @Bean
        public DatabaseClient databaseClient() {
            DatabaseClient databaseClient = new DatabaseClient();
            databaseClient.setUrl("http://localhost");
            databaseClient.setPort(3306);
            return databaseClient;
        }
    }
}

테스트 실행 결과 값

왜 이런 결과가 나왔을까? 너무나 당연한 얘기겠지만 객체를 생성하는 단계에는 url 과 port 의 값이 주어지지 않았고 객체가 생성된 후에 setUrlsetPort 를 호출해주어야 port 와 url 이 올바르게 생성된다. 위 코드에서 lifeCycleTest() 안에 있는 client 는 port 와 url 을 가지고 있는 상태로 생성된 객체이다. 위 코드에 client.connect() 를 추가해서 테스트를 다시 실행시키면 아래와 같은 결과를 얻을 수 있다.

 

생성 된 객체를 초기화(connect) 시킨 결과

정리

스프링 빈의 이벤트 라이프사이클

  1. 스프링 컨테이너생성
  2. 스프링 빈 생성
  3. 의존관계주입
  4. 초기화콜백 사용
  5. 소멸전콜백
  6. 스프링 종료
ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);

위 코드의 실행은 다음과 같다.

  1. 스프링 컨테이너 생성
  2. 스프링 빈 생성
  3. 의존관계 주입
  4. 객체 초기화 콜백

 

 

'Development > Java' 카테고리의 다른 글

스프링의 핵심 원리 - 기본편(3)  (0) 2021.12.14
스프링의 핵심 원리 - 기본편(2)  (0) 2021.12.14
스프링의 핵심 원리 - 기본편  (0) 2021.12.14
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기