티스토리 뷰

빈 생명주기 콜백

DB 커넥션 풀이나, 네트워크 소켓같은 경우 애플리케이션 시작 시점에 필요한 연결을 미리 해두고, 애플리케이션 종료 시점에 연결을 모두 종료하려면 객체의 초기화와 종료 작업 필요

 

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 message) {
    	System.out.println("call: " + url + " message = " + message);
    }
    
    //서비스 종료시 호출
    public void disconnect() {
    	System.out.println("close: " + url);
    }
}
@Test
public void lifeCycleTest() {
    ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);
    NetworkClient client = ac.getBean(NetworkClient.class);
    ac.close(); //스프링 컨테이너를 종료, ConfigurableApplicationContext 필요
}

@Configuration
static class LifeCycleConfig {
  @Bean
  public NetworkClient networkClient() {
      NetworkClient networkClient = new NetworkClient();
      networkClient.setUrl("http://hello-spring.dev");
      return networkClient;
  }
}

- 수정자(setter) 주입을 통해서 setUrl()이 호출되면 url이 존재해야 하는데, 모두 다 null 값으로 나온다.

- 스프링 빈의 이벤트 라이프사이클(LifeCycle)

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

 

- 초기화 콜백 : 빈이 생성되고, 빈의 의존관계 주입이 완료된 후 호출

- 소멸전 콜백 : 빈이 소멸되기 직전에 호출

 

스프링은 크게 3가지 방법으로 빈 생명주기 콜백을 지원한다.

- 인터페이스 (InitializingBean, DisposableBean)

- 설정 정보에 초기화 메서드, 종료 메서드 지정

- @PostConstruct, @PreDestroy Annotation 지원

 

인터페이스 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);
    }
    
    @Override
    public void afterPropertiesSet() throws Exception {
    	connect();
    	call("초기화 연결 메시지");
    }
    
    @Override
    public void destroy() throws Exception {
    	disConnect();
    }
}

초기화, 소멸 인터페이스 단점

- 스프링 전용 인터페이세 의존

- 초기화, 소멸 메서드의 이름을 변경할 수 없다.

- 외부 라이브러리에 적용할 수 없다

 

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

@Configuration
static class LifeCycleConfig {

    @Bean(initMethod = "init", destroyMethod = "close")
    public NetworkClient networkClient() {
        NetworkClient networkClient = new NetworkClient();
        networkClient.setUrl("http://hello-spring.dev");
        return networkClient;
    }
}

NetworkClient.java의 init(), close() 메서드를 지정해줄 수 있다.

- 메서드 이름을 자유롭게 할 수 있으며, 스프링 코드에 의존하지 않는다.

- 설정 정보를 사용하기 때문에 외부 라이브러리에도 초기화, 종료 메서드를 적용할 수 있다.

 

@Bean의 destoryMethod에는 특별한 기능이 있다.

- 라이브러리는 대부분 close, shutdown이라는 이름의 종료 메서드를 사용한다.

- destroyMethod는 기본값이 "(inferred)" (추론)으로 등록되어 있다.

 

Annotation @PostConstruct, @Predestroy

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

@PreDestroy
public void close() {
    System.out.println("NetworkClient.close");
    disConnect();
}

- 최신 스프링에서 가장 권장하는 방법, Annotation 하나만 붙이면 되서 매우 편리한 방법

- 스프링에 종속적인 기술이 아닌 JSR-250이라는 자바 표준이다.

- 컴포넌트 스캔과 어울린다.

- 단, 외부 라이브러리에는 적용하지 못한다는 것이다.  외부 라이브러리를 초기화, 종료 해야 하면 @Bean의 initMethod, destoryMethod를 사용하자

 

 

출처: 스프링 핵심 기본 원리편

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
TAG
more
«   2025/02   »
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
글 보관함