스프링/기본편

빈 생명주기 콜백

수풀속의고라니 2022. 5. 23. 06:21
728x90

스프링 빈이 생성되거나 죽기 직전에 스프링이 메서드를 호출할 수 있는 기능

생성되서 초기화 될 때 호출하고, 빈이 사라지기 직전에 안전하게 종료할 수 있는 메서드를 호출

 

빈 생명주기 콜백


 

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

 

스프링 환경설정, 실행

 

public class BeanLifeCycleTest {

    @Test
    public void lifeCycleTest(){
        ConfigurableApplicationContext ac = new AnnotationConfigApplicationContext(LifeCycleConfig.class);
        NetworkClient client = ac.getBean(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, DisposableBean


public class NetworkClient  implements InitializingBean, DisposableBean {

 

위의 두 인터페이스를 상속받고

 

//의존관계 주입이 끝나면 호출해준다.
@Override
public void afterPropertiesSet() throws Exception {
    System.out.println("NetworkClient.afterPropertiesSet");
    connect();
    call("초기화 연결 메세제");
}

//빈이 종료될 때 호출
@Override
public void destroy() throws Exception {
    System.out.println("NetworkClient.destroy");
    disconnect();
}

 

위의 두개를 오버라이딩 받으면

 

 

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


빈을 등록하는 시점에 초기화와 소멸을 지정할 수 있음

 

 

public void init(){
    System.out.println("NetworkClient.init");
    connect();
    call("초기화 연결 메세제");
}

public void close(){
    System.out.println("NetworkClient.close");
    disconnect();
}

 

위와 같이 코드를 고침

 

@Configuration
static class LifeCycleConfig{
    @Bean(initMethod = "init", destroyMethod = "close")
    public NetworkClient networkClient(){

 

설정파일 부분도 위와 같이 고쳐주면 인터페이스를 사용했을 때처럼 결과가 나오게 된다.

 

 

@Bean으로 등록할 때만 발생하는 destroy의 특별한 기능이 있다.

 

종료 메서드 추론

 

애노테이션 @PostConstruct, @PreDestroy


결론은 그냥 이걸 쓰자는 것

 

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

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

 

코드 위와 같이 변경

 

@Bean
public NetworkClient networkClient(){

 

빈만 붙여서 스프링 빈으로 등록만 시켜주면 잘 동작

 

 

728x90