[스프링 핵심 원리 - 기본편] 08. 빈 생명주기 콜백

Turtle·2024년 6월 16일
0
post-thumbnail

🙄빈 생명주기 콜백 시작

데이터베이스 커넥션 풀이나 네트워크 소켓처럼 애플리케이션 시작 시점에 필요한 연결을 미리 해두고 애플리케이션 종료 시점에 연결을 모두 종료하는 작업을 진행하려면 객체의 초기화와 종료 작업이 필요하다.

  • ✔️스프링 빈의 라이프 사이클

    스프링 컨테이너 생성 → 스프링 빈 생성 → 의존관계 주입 → 초기화 콜백 → 사용 → 소멸 전 콜백 → 스프링 종료

    ✔️초기화 콜백 : 빈이 생성되고 빈의 의존관계 주입이 완료된 후 호출
    ✔️소멸 전 콜백 : 빈이 소멸되기 직전에 호출

  • ✔️참고: 객체 생성과 초기화를 분리

    • 생성자는 필수 정보를 받고 메모리를 할당해서 객체를 생성하는 책임을 진다.
    • 반면에 초기화는 이렇게 생성된 값들을 활용해서 외부 커넥션을 연결하는 등 무거운 책임을 진다.
    • 따라서 생성자 안에서 무거운 초기화 작업을 함께 하는 것 보다는 객체를 생성하는 부분과 초기화하는 부분을 명확하게 나누는 것이 좋다.

🙄인터페이스 InitializingBean, DisposableBean

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);
    }

	// ✔️InitializingBean 인터페이스 구현
    @Override
    public void afterPropertiesSet() throws Exception {
        connect();
        call("초기화 연결 메시지");
    }

	// ✔️DisposableBean 인터페이스 구현
    @Override
    public void destroy() throws Exception {
        disconnect();
    }
}
public class BeanLifeCycleTest {
    @Test
    public void lifeCycleTest() {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);
        NetworkClient networkClient = ac.getBean("networkClient", NetworkClient.class);
        ac.close();
    }

    @Configuration
    static class LifeCycleConfig {
        @Bean
        public NetworkClient networkClient() {
            NetworkClient networkClient = new NetworkClient();
            networkClient.setUrl("http://hello-spring.dev");
            return networkClient;
        }
    }
}
  • ✔️실행
    • InitializingBean : afterPropertiesSet() 메서드로 초기화를 지원한다.
    • Disposable : destroy() 메서드로 소멸을 지원한다.
    • 스프링 컨테이너 생성 후 생성자를 호출하고 의존관계를 주입한다.
    • 그 다음 초기화 메서드가 주입 완료 후에 적절하게 호출이 된다.
    • 스프링 컨테이너 종료가 호출되자 소멸 메서드도 호출된다.

🙄빈 등록 초기화, 소멸 메서드

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() {
        connect();
        call("초기화 연결 메시지");
    }

	// ✔️소멸 메서드
    public void close() {
        disconnect();
    }
}
public class BeanLifeCycleTest {
    @Test
    public void lifeCycleTest() {
        AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);
        NetworkClient networkClient = ac.getBean("networkClient", NetworkClient.class);
        ac.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;
        }
    }
}
  • ✔️실행
    • 설정 정보에 초기화 소멸 메서드 지정
    • 메서드 이름을 자유롭게 설정 가능
    • InitializingBean, Disposable과 같이 스프링에 의존적이지 않다는 점이 있다.

🙄어노테이션 @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 message) {
        System.out.println("call: " + url + ", message: " + message);
    }

    public void disconnect() {
        System.out.println("close: " + url);
    }

    @PostConstruct
    public void init() {
        connect();
        call("초기화 연결 메시지");
    }

    @PreDestroy
    public void close() {
        disconnect();
    }
}
  • ✔️특징
    • 최신 스프링에서 권장되는 방법
    • 어노테이션 하나만 붙이면 되므로 매우 편리하다.
    • @PostConstruct, @PreDestroy를 사용하자.

0개의 댓글