Programming-[Backend]/Spring

[스프링 기초] 15. 빈 생명주기 콜백 : initMethod, destroyMethod, @PostConstruct, @PreDestroy

컴퓨터 탐험가 찰리 2021. 7. 11. 17:16
728x90
반응형

1. 기본 개념

 

빈 생명주기 콜백은 빈이 생성되거나 소멸되는 시점에 설정해둔 메서드가 실행되게 함으로써 초기 설정을 해주거나, 연결을 종료하는 등의 기능을 한다. 스프링 빈은 '객체 생성 -> 의존관계 주입' 의 2단계를 거치게 되는데(생성자 주입의 경우 한번에 처리), 의존관계 주입 후 값을 설정해주는 단계를 초기화 단계라고 한다. 이 초기화 단계를 알리기 위해 스프링 빈은 의존관계 주입 후 콜백 메서드를 통해서 초기화 시점을 알려주는 다양한 기능을 제공한다. 그리고 스프링은 스프링 컨테이너가 종료되기 전에도 소멸 콜백 메서드를 제공한다.

 

이렇게 객체의 생성과 초기화가 분리된 이유는 SRP의 원칙을 지키기 위해서이기도 하고, 초기화 작업이 외부와 커넥션을 연결하는 등 무거운 작업을 하기도 하기 때문이다. 일단 메모리상에 객체들을 지정해주고, 이후에 무거운 작업들을 처리하는 방식인 것이다. 다만, 초기화 작업이 무겁지 않은 경우에는 생성과 초기화 작업을 한번에 처리하는 것이 좋을 수도 있다.

 

 


 

2. InitializingBean, DisposableBean

각각 afterPropertiesSet, destroy 메서드를 갖고 있다. 초기화 및 종료 시 작동하므로 네트워크 연결 및 종료 로직을 적용하기에 적합하다. 다만, 스프링에 의존하는 메서드라서, 외부 라이브러리 등과 함께 사용하기 어려울 수 있다.

 

네트워크 연결을 초기화하고 종료하는 NetworkClient 클래스를 작성해보자. 실제로 연결은 하지 않고, 문자열들을 출력해서 네트워크 연결을 가정해보는 것이다. 서비스 시작과 종료 시에 파라미터로 받아온 url에 연결 및 연결 종료를 하는 코드이다. InitializingBean과 DisposableBean을 상속받아서, afterPropertiesSet, destory 메서드를 사용한다.

 

 

아래와 같이 테스트해보면, 빈 사이클을 이해할 수 있다. 우선 LifeCyleConfig를 만든다. 24번 줄에서 객체를 생성하고, setUrl로 NetworkClient 빈의 속성을 set 해준다. lifeCyleTest 부분에서 LifeCycleConfig 설정 정보를 바탕으로 컨테이너를 생성하고 테스트하면, 콘솔창에서 "call ... " 부분까지 출력되는 것을 확인할 수 있다. 이것은

 

컨테이너 생성 -> 빈 등록(24번줄) 및 의존관계 설정: 콘솔창에서 생성자 호출 -> property 설정(25번줄) -> afterProperties에 의해 connect() 및 call() 메서드 실행

 

순으로 실행되는 결과를 보여준다. 주석처리해놓은 부분을 주석 해제하면, 빈을 조회하고 close() 하는 부분이 적용되어 콘솔창에서 빨간 마크 아래 부분이 실행된다. 컨테이너의 .close() 메서드를 이용하기 위해서 ApplicationContext가 아닌 ConfigurableApplicationContext를 적용했다(물론 AnnotationConfigApplicationContext도 close() 메서드를 지원한다).

 

 

 


3. InitMethod, destroyMethod

@Bean 어노테이션의 속성 정보를 작성하여 afterPropertiesSet(), destroy() 메서드와 동일한 기능을 제공할 수 있다. InitializingBean, disposableBean이 코드를 상속받는데 비해서, 이것은 설정 정보를 이용하는 것이므로 코드를 고칠 수 없는 외부 라이브러리에도 초기화, 종료 메서드를 적용할 수 있다.

 

빈 객체에서 implements InitializingBean, disposableBean 으로 작성했던 부분을 제외한다. 그리고 각 메서드를 init, destroy 메서드로 명명한다.

 

 

빈 설정 정보 부분에서 @Bean 수동 설정 부분에, initMethod, destroyMethod를 메서드 이름으로 설정한다. 테스트를 돌려보면 정상작동하는 것을 확인할 수 있다.

-destroyMethod의 추론 기능

 destoryMethod는 외부라이브러리에 적용 시, 자동으로 빈 소멸 시 close, shutdown 이름으로 된 메서드를 실행하여 해당 빈을 종료시켜준다. 이것은 대부분의 라이브러리의 종료 메서드의 이름이 close, shutdown으로 되어있기 때문이다. 만약 이런 추론 기능을 사용하고 싶지 않다면, destroyMethod의 값을 빈 스트링으로 주면된다(destroyMethod="")

 

 


 

4. @PostConstruct, @PreDestroy

조금 더 편한 방법으로, @PostConstruct와 @PreDestory를 적용하는 방법이 있다. 이 어노테이션은 javax에서 import 해와서 자바의 JSR-250 표준 기술이므로 꼭 스프링에 의존하지 않아도 되는 장점이 있다. 그러나, 외부 라이브러리와 연동되지는 않으므로 외부 라이브러리를 초기화, 종료해야 한다면 initMethod, destroyMethod를 사용해야만 한다.

 

 


참조

1. 인프런_스프링 핵심 원리 기본편_김영한 님 강의

www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%ED%95%B5%EC%8B%AC-%EC%9B%90%EB%A6%AC-%EA%B8%B0%EB%B3%B8%ED%8E%B8/dashboard

728x90
반응형